Dependency injection 将Unity挂钩到WebAPI过滤器属性中

Dependency injection 将Unity挂钩到WebAPI过滤器属性中,dependency-injection,asp.net-web-api,unity-container,Dependency Injection,Asp.net Web Api,Unity Container,我的ASP.NET Web API项目中所有控制器的Unity都运行得非常好,只需使用NuGet框中的默认设置即可。我还成功地将它连接到MVC过滤器属性上,但对于ASP.NET Web API过滤器属性似乎做不到这一点 如何扩展此默认实现以将依赖项注入ActionFilterAttribute,例如 public class BasicAuthenticationAttribute : ActionFilterAttribute { [Dependency] public IMy

我的ASP.NET Web API项目中所有控制器的Unity都运行得非常好,只需使用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));


问题在于属性类是由.NET创建的,而不是由WebAPI框架创建的

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

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

我已经从你的答案中找到了静态方法的概念,它是有效的。感觉有点不对劲,但考虑到我找不到其他方法,我会接受的:)-谢谢!我使用静态工厂的唯一原因是,在注册UnityContainer之后,我找不到从WebAPI获取UnityContainer的方法。但这没什么问题。你不想为每个请求或每次请求都创建新的容器,所以我相信该模式是有效的。我同意-我想重复使用同一个容器,但我希望能够在过滤器属性上方的一层上实现这一点。这是我唯一不满意的一点——不是重复使用同一个容器
(IUnityContainer)container;
container.RegisterType<IApiUserService, MyApiUserServiceImpl>();
...
var service = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IApiUserService));
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"));
    }
}
config.Filters.Add(new MyFilterAttribute(UnityConfig.GetConfiguredContainer()));