Autofac 获取当前身份

r3p*_*ica 1 c# autofac asp.net-web-api

我有一个服务,几乎每个方法都需要当前用户执行。在我开始使用 autofac 之前,我基本上创建了一个像这样的公共属性:

private IOrderProvider _orderProvider;

public IOrderProvider OrderProvider => _orderProvider ?? (_orderProvider = new OrderProvider((ClaimsIdentity)User.Identity));
Run Code Online (Sandbox Code Playgroud)

因为这是控制器上的公共属性,所以它可以访问User。现在使用 autofac 我在StartupConfig中注册我的服务。当然,我无权访问那里的用户

有没有办法将当前用户注入到OrderProvider构造函数中,或者有其他方法来获取它?

Nko*_*osi 5

用户主体可以通过HttpContext.Current.User. 然而,将代码与 HttpContext 紧密耦合是不受欢迎的,因为它对单元测试不太友好。因此,创建一个公开您想要的服务。

using System.Security.Principal;
public interface IPrincipalProvider
{
    IPrincipal User { get; }
}
Run Code Online (Sandbox Code Playgroud)

生产中的实现可能如下所示。

using System.Security.Principal;    
public class DefaultPrincipalProvider : IPrincipalProvider
{
    public IPrincipal User
    {
        get
        {
            return HttpContext.Current.User;
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

完成后更新依赖类以使用抽象

public class OrderProvider : IOrderProvider
{
    private readonly ClaimsIdentity identity;
    public OrderProvider(IPrincipalProvider provider) {
        identity = (ClaimsIdentity)provider.User.Identity;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像往常一样在启动时注册提供程序

//...other code removed for brevity

builder.RegisterType<DefaultPrincipalProvider>().As<IPrincipalProvider>();
builder.RegisterType<OrderProvider>().As<IOrderProvider>();

//...other code removed for brevity
Run Code Online (Sandbox Code Playgroud)

该服务应该注入所有内容

public class Service {
    private readonly IOrderProvider _orderProvider;

    public Service(IOrderProvider orderProvider) {
        _orderProvider = orderProvider;
    }

    public IOrderProvider OrderProvider => _orderProvider;
}
Run Code Online (Sandbox Code Playgroud)