问题
How can i inject the following dependencies ??
public class Authenticate : AuthorizeAttribute
{
[Dependency]
public IAuthenticate AuthenticateLibrary { get; set; }
[Dependency]
public ILibrary BaseLibrary { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
}
}
I am using Unity 2 to inject all the controllers. Is there a tutorial for Unity 2 and injecting dependencies into filters?
回答1:
Brad Wilson has a good series on Service Location which includes how to create your own filter provider that can support dependency injection: http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html (Scroll down to the section "Adding Dependency Injection to Filters").
- Copy the code he provides for the UnityFilterAttributeFilterProvider.cs.
UnitFilterAttributeFilterProvider.cs
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider {
private IUnityContainer _container;
public UnityFilterAttributeFilterProvider(IUnityContainer container) {
_container = container;
}
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;
}
}
- Modify the Application_Start of the global.asax.cs to make the UnityFilterAttributeFilterProvider the filter provider for your MVC app.
.
protected void Application_Start() {
// ...
var oldProvider = FilterProviders.Providers.Single(
f => f is FilterAttributeFilterProvider
);
FilterProviders.Providers.Remove(oldProvider);
var container = new UnityContainer();
var provider = new UnityFilterAttributeFilterProvider(container);
FilterProviders.Providers.Add(provider);
// ...
}
- Decorate the properties that you want Unity to inject a value for with the [Dependency] attribute. And then you should be good to go.
回答2:
Since Unity is not instantiating the Filters, it cannot inject them. You would have to resort to service locator pattern such as in the following:
public class Authenticate : AuthorizeAttribute
{
public IAuthenticate AuthenticateLibrary { get; private set; }
public ILibrary BaseLibrary { get; private set; }
public Authenticate()
{
AuthenticateLibrary = DependencyResolver.Current.GetService<IAuthenticate>();
BaseLibrary = DependencyResolver.Current.GetService<ILibrary >();
}
...
}
回答3:
For all people that (like me) arrived here looking for a solution in MVC4 + Unity, although the accepted answers works perfectly, I wanted to add that now you can also simply override the GetFilters method of the FilterAttributeFilterProvider class:
public class CustomFilterProvider : FilterAttributeFilterProvider
{
private readonly IUnityContainer container;
public CustomFilterProvider(IUnityContainer container)
{
this.container = container;
}
public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext, actionDescriptor);
var enumerable = filters as IList<Filter> ?? filters.ToList();
foreach (var filter in enumerable)
{
container.BuildUp(filter.Instance.GetType(), filter.Instance);
}
return enumerable;
}
}
Cheers.
来源:https://stackoverflow.com/questions/6121050/mvc-3-unity-2-inject-dependencies-into-a-filter