【问题标题】:Implementing IAuthenticationFilter, Unit of Work and Dependency Injection实现 IAuthenticationFilter、工作单元和依赖注入
【发布时间】:2015-08-05 07:49:33
【问题描述】:

我有一个 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) {}
}

【问题讨论】:

  • 由于 BasicAuthenticatior 是一个 Attribute 并且可能被这样使用,所以不会有 DependencyInjection,因为它不会由 unity 而是由 mvc 框架实例化。您可以尝试在 BasicAuthetnicator 构造函数中获取统一容器。
  • @TGlatzer,你是对的,框架实例化了过滤器。但是,您可以创建一个自定义过滤器提供程序,它将对过滤器执行依赖注入。

标签: c# entity-framework unity-container asp.net-web-api2 unit-of-work


【解决方案1】:

您将需要创建一个自定义 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;
    }
}

接下来在应用程序启动时,您需要将默认过滤器提供程序替换为上面的自定义提供程序:

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);

我通常使用Unity bootstrapper for ASP.NET Web API所以我把上面的代码放在RegisterTypes()之后的UnityConfig.cs中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 2018-02-11
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    相关资源
    最近更新 更多