如何使用 Autofac 根据用户上下文解析组件

How to resolve component based on user context using Autofac

我有一项服务需要 UserName 在构造期间传入。 UserName 将来自当前 Web 请求 cookie 或查询字符串。

builder.Register((c,p) => {
    var accessService = c.Resolve<IAccessService>();
    var access = accessService.GetBySite(Request.QueryString["username"]);
    return new JsonWebRequest(access.Site, access.Token);
}).InstancePerRequest();

尽管收到此错误消息,但我已尝试按上述方式注册

Request is not available in this context

您应该使用 HttpContext.Current 从活动上下文中访问信息。

builder.Register((c,p) => {
    var accessService = c.Resolve<IAccessService>();
    var request = HttpContext.Current.Request; 
    var access = accessService.GetBySite(request.QueryString["username"]);
    return new JsonWebRequest(access.Site, access.Token);
}).InstancePerRequest();

另一种方法是使用 AutofacWebTypesModule,它将导入 HttpRequestBase 的注册。此模块可使用 Autofac MVC5 nuget package

builder.RegisterModule<AutofacWebTypesModule>();
builder.Register((c,p) => {
    var accessService = c.Resolve<IAccessService>();
    var request = c.Resolve<HttpRequestBase>();  
    var access = accessService.GetBySite(request.QueryString["username"]);
    return new JsonWebRequest(access.Site, access.Token);
}).InstancePerRequest();

顺便说一句,为了测试目的和更大的灵活性,我建议您创建一个 IUserNameProvider 界面,它将为您提供一个用户名

public interface IUserNameProvider 
{
    String UserName { get; }
}


public class QueryStringUserNameProvider 
{
    public QueryStringUserNameProvider(HttpRequestBase request)
    {
        this._request = request; 
    }

    private readonly HttpRequestBase _request; 


    public String UserName 
    {
        get 
        {
            return this._request.QueryString["UserName"];
        }
    }
}

你可以这样使用它:

builder.RegisterModule<AutofacWebTypesModule>();
builder.RegisterType<QueryStringUserNameProvider>()
       .As<IUserNameProvider>()
       .InstancePerRequest(); 
builder.Register((c,p) => {
    var accessService = c.Resolve<IAccessService>();
    var userNameProvider = c.Resolve<IUserNameProvider>(); 
    var access = accessService.GetBySite(userNameProvider.UserName);
    return new JsonWebRequest(access.Site, access.Token);
}).InstancePerRequest();