将Unity连接到Web API过滤器属性

时间:2013-06-13 08:07:34

标签: dependency-injection asp.net-web-api unity-container

我的Unity运行非常适合我的ASP.NET Web API项目中的所有控制器 - 只使用NuGet框中的默认设置。我还设法将其连接到MVC过滤器属性 - 但似乎无法对ASP.NET Web API过滤器属性执行相同的操作。

如何扩展此默认实现以将依赖项注入ActionFilterAttribute,例如......

public class BasicAuthenticationAttribute : ActionFilterAttribute
{
    [Dependency]
    public IMyService myService { get; set; }

    public BasicAuthenticationAttribute()
    {
    }
}

此过滤器使用属性

应用于控制器
[BasicAuthentication]

我很确定我需要连接Unity容器以便它处理属性类的创建,但是需要一些关于从哪里开始的线索,因为它不使用与MVC过滤器相同的可扩展点。

我只想添加,我尝试过的其他内容包括服务位置而不是依赖注入,但是你得到的DependencyResolver与你配置的不一样。

// null
var service = actionContext.Request.GetDependencyScope().GetService(typeof(IMyService));

或者

// null
var service = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IApiUserService));

1 个答案:

答案 0 :(得分:7)

问题是Attribute类是由.NET创建的,而不是由WebAPI框架创建的。

在进一步阅读之前,您是否忘记使用IApiUserService配置DependencyResolver?

(IUnityContainer)container;
container.RegisterType<IApiUserService, MyApiUserServiceImpl>();
...
var service = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IApiUserService));

我创建了一个App_Start \ UnityConfig类来保存我的UnityContainer:

public class UnityConfig {
    #region Unity Container
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    /// <summary>
    /// Gets the configured Unity container.
    /// </summary>
    public static IUnityContainer GetConfiguredContainer() {
        return container.Value;
    }
    #endregion

    public static void Configure(HttpConfiguration config) {
        config.DependencyResolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
    }

    /// <summary>Registers the type mappings with the Unity container.</summary>
    /// <param name="container">The unity container to configure.</param>
    /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
    /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
    private static void RegisterTypes(IUnityContainer container) {
        // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
        // container.LoadConfiguration();

        // TODO: Register your types here
        // container.RegisterType<IProductRepository, ProductRepository>();
        container.RegisterType<MyClass>(new PerRequestLifetimeManager(), new InjectionConstructor("connectionStringName"));
    }
}

UnityDependencyResolverPerRequestLifetimeManager来自this blog post和Unity.WebApi(Project / Nuget Package)我内化了。 (因为它是一个引导程序)

当我需要在其他代码中使用UnityContainer时,我将其传递给构造函数:

config.Filters.Add(new MyFilterAttribute(UnityConfig.GetConfiguredContainer()));