实现IAuthenticationFilter,工作单元和依赖注入

VAU*_*er1 1 c# entity-framework unity-container unit-of-work asp.net-web-api2

我有一个Web API 2项目正在实现自定义IAuthenticationFilter,如下所示.

我的问题是Unity没有在BasicAuthenticator类中注入UnitOfWork.正如预期的那样,Unity成功地在控制器中注入了UnitOfWork.

public class BasicAuthenticator : Attribute, IAuthenticationFilter
{
    [Dependency]
    public UnitOfWork UoW { get; set; }

    public bool AllowMultiple { get { return false; } }     

    public Task AuthenticateAsync(HttpAuthenticationContext context,
                                  CancellationToken cancellationToken)
    {
        // ignore missing implementation
        context.Principal = new ClaimsPrincipal(new[] { id });     
        return Task.FromResult(0);
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
                            CancellationToken cancellationToken) {}
}
Run Code Online (Sandbox Code Playgroud)

Ran*_*ica 6

您需要创建一个IFilterProvider将在适用的过滤器上执行BuildUp()的自定义.BuildUp操作会将所有依赖项注入过滤器.

这是一个UnityFilterProvider,它可以做到这一点:

public class UnityFilterProvider : ActionDescriptorFilterProvider, IFilterProvider
{
    private readonly IUnityContainer container;

    public UnityFilterProvider(IUnityContainer container)
    {
        this.container = container;
    }

    public new IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
    {
        var filters = base.GetFilters(configuration, actionDescriptor);

        foreach (var filter in filters)
        {
            container.BuildUp(filter.Instance.GetType(), filter.Instance);
        }

        return filters;
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来在应用程序启动时,您需要使用上面的自定义提供程序替换默认筛选提供程

var providers = GlobalConfiguration.Configuration.Services.GetFilterProviders().ToList();
GlobalConfiguration.Configuration.Services.Add(typeof(System.Web.Http.Filters.IFilterProvider),
                                                new UnityFilterProvider(container));

var defaultprovider = providers.First(p => p is ActionDescriptorFilterProvider);
GlobalConfiguration.Configuration.Services.Remove(typeof(System.Web.Http.Filters.IFilterProvider), defaultprovider);
Run Code Online (Sandbox Code Playgroud)

我通常使用.NET Web APIUnity引导程序,所以我将上面的代码放在UnityConfig.cs之后RegisterTypes().