How to resolve component based on user context using Autofac

1.6k views Asked by At

I have a service that requires a UserName to be passed in during construction. The UserName will come from the current web request either cookie or query string.

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

I've tried to register as above although I receive this error message

Request is not available in this context

1

There are 1 answers

0
Cyril Durand On BEST ANSWER

You should use HttpContext.Current to access the information from the active context.

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

Another way of doing it is by using the AutofacWebTypesModule which will import registration for HttpRequestBase. This module is available using the 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();

By the way, for testing purpose and more flexibility I would recommend you to create a IUserNameProvider interface that will get you a username

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"];
        }
    }
}

You can use it like this :

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