我讀過的一定數量的點出文章如何做到這一點,即:噴吹類爲驗證屬性使用Unity 2和MVC 3
Brad Wilsons excellent tutorial
這些似乎的確工作得很好,但是當我遵循的一些準則從這裏
Securing your ASP.NET MVC 3 Application
我似乎來了一個收割機。對我來說,問題是我將我的AuthorizationAttribute添加爲GlobalFilter,而不是僅僅裝飾控制器/操作。儘管依賴解析器似乎被調用,並且在我重寫AuthorizeAttribute的OnAuthorization()方法的代碼的實際部分中設置公開的[Dependancy]屬性時,我的public [Dependency]屬性爲null。
當我從全局過濾器中刪除它並裝飾一個控制器,它似乎工作。
如果需要更多信息,我可以發佈代碼。
編輯: 要在此位置進一步擴大是我的一些代碼:
的global.asax.cs
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// If I have this here the my [Dependency] attribute does not keep it's value
// If I remove it and decorate the controller the [Dependency] attribute keeps it value
filters.Add(new BasicAuthenticationAttribute());
filters.Add(new HandleErrorAttribute());
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// injection of services and data contexts
var container = new UnityContainer();
// injections for services
RegisterUnityServices(container);
// Filter provides to allow injection into attribute filters
RegisterUnityFilters(container);
}
private void RegisterUnityServices(UnityContainer container)
{
container.RegisterType<IDataContext, CDAXDataContext>();
container.RegisterType<IUploadService, UploadService>();
container.RegisterType<IAuthenticationService, AuthenticationService>();
// add more services here ...
DependencyResolver.SetResolver(new Models.UnityDependencyResolver(container));
}
private void RegisterUnityFilters(UnityContainer container)
{
var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
FilterProviders.Providers.Remove(oldProvider);
var provider = new UnityFilterAttributeFilterProvider(container);
FilterProviders.Providers.Add(provider);
}
從布拉德·威爾遜的例子採取
我統一類:
public class UnityDependencyResolver : IDependencyResolver
{
readonly IUnityContainer _container;
public UnityDependencyResolver(IUnityContainer container)
{
this._container = container;
}
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch
{
return new List<object>();
}
}
}
And
public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider
{
private IUnityContainer _container;
public UnityFilterAttributeFilterProvider(IUnityContainer container)
{
_container = container;
}
public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext, actionDescriptor);
foreach (var filter in filters)
{
_container.BuildUp(filter.Instance);
}
return filters;
}
protected override IEnumerable<FilterAttribute> GetControllerAttributes(
ControllerContext controllerContext,
ActionDescriptor actionDescriptor)
{
var attributes = base.GetControllerAttributes(controllerContext,
actionDescriptor);
foreach (var attribute in attributes)
{
_container.BuildUp(attribute.GetType(), attribute);
}
return attributes;
}
protected override IEnumerable<FilterAttribute> GetActionAttributes(
ControllerContext controllerContext,
ActionDescriptor actionDescriptor)
{
var attributes = base.GetActionAttributes(controllerContext,
actionDescriptor);
foreach (var attribute in attributes)
{
_container.BuildUp(attribute.GetType(), attribute);
}
return attributes;
}
}
而My BasicAuthenticationAttribute的基礎是我設置了[Dependency]屬性,但是當方法被觸發時並沒有保持這個值。
public class BasicAuthenticationAttribute : AuthorizeAttribute
{
[Dependency]
public IAuthenticationService Authentication { get; set; }
private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
// code here that uses the Authentication attribute but it's null
}
不,我沒有。我覺得奇怪的是,如果我裝飾控制器,但它不起作用,如果我把它放在global.ascx中。我會給你的方法去,但我真的希望通過使用Unity實現DIP。目前它正在工作,但解釋方法是我裝飾控制器,而不是將其包含在全局文件中。 – dreza 2012-04-20 19:52:09
我發現了相同的行爲,在控制器中工作正常,但沒有在屬性/過濾器中...它只是不在那裏,所以我需要調用DependencyResolver。來自http://stackoverflow.com/users/759701/ethan-cabiac的有趣評論「它不是關於它們是否被註冊,而是關於它們是如何實例化的。本質上,框架調用新的Authenticate(),繞過任何DI容器「在這個問題http://stackoverflow.com/questions/6121050/mvc-3-unity-2-inject-dependencies-into-a-filter – w4ik 2012-04-20 20:36:01