3 回答

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超4個贊
好的,您已經(jīng)邁出了很好的第一步,認(rèn)識到Web.config只是另一個依賴項(xiàng),并將其包裝到ConfigProvider中進(jìn)行注入是一個很好的解決方案。
但是,您開始陷入MVC的設(shè)計(jì)問題之一-即,為了實(shí)現(xiàn)DI友好性,屬性應(yīng)僅提供元數(shù)據(jù),而從不實(shí)際定義行為。這不是測試方法的問題,而是濾波器設(shè)計(jì)方法的問題。
正如文章中指出的那樣,您可以通過將操作過濾器屬性分為兩部分來解決此問題。
該屬性不包含任何用于標(biāo)記控制器和操作方法的行為。
一個DI友好類,該類實(shí)現(xiàn)IActionFilter并包含所需的行為。
該方法是使用IActionFilter來測試屬性的存在,然后執(zhí)行所需的行為??梢詾閯幼鬟^濾器提供所有依賴項(xiàng),然后在組成應(yīng)用程序時將其注入。
IConfigProvider provider = new WebConfigProvider();
IActionFilter filter = new MaxLengthActionFilter(provider);
GlobalFilters.Filters.Add(filter);
注意:如果您需要過濾器的任何依賴項(xiàng)以使生命周期短于單例,則需要GlobalFilterProvider在此答案中使用as 。
MaxLengthActionFilter的實(shí)現(xiàn)如下所示:
public class MaxLengthActionFilter : IActionFilter
{
public readonly IConfigProvider configProvider;
public MaxLengthActionFilter(IConfigProvider configProvider)
{
if (configProvider == null)
throw new ArgumentNullException("configProvider");
this.configProvider = configProvider;
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
var attribute = this.GetMaxLengthAttribute(filterContext.ActionDescriptor);
if (attribute != null)
{
var maxLength = attribute.MaxLength;
// Execute your behavior here, and use the configProvider as needed
}
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var attribute = this.GetMaxLengthAttribute(filterContext.ActionDescriptor);
if (attribute != null)
{
var maxLength = attribute.MaxLength;
// Execute your behavior here, and use the configProvider as needed
}
}
public MaxLengthAttribute GetMaxLengthAttribute(ActionDescriptor actionDescriptor)
{
MaxLengthAttribute result = null;
// Check if the attribute exists on the controller
result = (MaxLengthAttribute)actionDescriptor
.ControllerDescriptor
.GetCustomAttributes(typeof(MaxLengthAttribute), false)
.SingleOrDefault();
if (result != null)
{
return result;
}
// NOTE: You might need some additional logic to determine
// which attribute applies (or both apply)
// Check if the attribute exists on the action method
result = (MaxLengthAttribute)actionDescriptor
.GetCustomAttributes(typeof(MaxLengthAttribute), false)
.SingleOrDefault();
return result;
}
}
并且,不應(yīng)包含任何行為的屬性應(yīng)如下所示:
// This attribute should contain no behavior. No behavior, nothing needs to be injected.
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class MaxLengthAttribute : Attribute
{
public MaxLengthAttribute(int maxLength)
{
this.MaxLength = maxLength;
}
public int MaxLength { get; private set; }
}
使用更寬松的耦合設(shè)計(jì),測試屬性的存在要簡單得多。
[TestMethod]
public void Base_controller_must_have_MaxLengthFilter_attribute()
{
var att = typeof(BaseController).GetCustomAttribute<MaxLengthAttribute>();
Assert.IsNotNull(att);
}

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個贊
最近,我在這里關(guān)于配置“問題”的問題越來越多。它們都有一個共同的基礎(chǔ)-您有幾個需要使用相同配置的項(xiàng)目,服務(wù)器和服務(wù)。我的建議是-停止使用Web.config。
將所有配置放入數(shù)據(jù)庫!添加一個包含所有配置鍵和值的表(或幾個表),并在應(yīng)用程序啟動時讀取它們(global.asax)。
這樣,您不必?fù)?dān)心將配置配置到每個項(xiàng)目中或?qū)⑵渥⑷氲讲煌臉?gòu)造函數(shù)中。

TA貢獻(xiàn)1883條經(jīng)驗(yàn) 獲得超3個贊
實(shí)際上,如果您正確地設(shè)計(jì)了過濾器,那不是不可以的(有理由將它們稱為過濾器)。篩選器的目的僅是確定何時執(zhí)行共享行為,而不應(yīng)實(shí)際執(zhí)行共享行為。應(yīng)該將其委派給一個處理程序,該處理程序的派生方式與ActionResult Microsoft在AuthorizeAttribute中所做的一樣(filterContext.Result僅當(dāng)需要運(yùn)行時才進(jìn)行設(shè)置)。
- 3 回答
- 0 關(guān)注
- 622 瀏覽
添加回答
舉報(bào)