Question

I have an asp.net MVC site which has many components registered using an InstancePerHttpRequest scope, however I also have a "background task" which will run every few hours which will not have an httpcontext.

I would like to get an instance of my IRepository which has been registered like this

builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>))
     .InstancePerHttpRequest();

How do I do this from a non http context using Autofac? I think the IRepository should use the InstancePerLifetimeScope

Was it helpful?

Solution

There are several ways of how you can do that:

  1. The best one in my opinion. You can register the repository as InstancePerLifetimeScope as you said. It works with HttpRequests and LifetimeScopes equally well.

    builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>))
        .InstancePerLifetimeScope();
    
  2. Your registration for HttpRequest may differ from registration for LifetimeScope, then you can have two separate registrations:

    builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>))
        .WithParameter(...)
        .InstancePerHttpRequest(); // will be resolved per HttpRequest
    
    builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>))
        .InstancePerLifetimeScope(); // will be resolved per LifetimeScope
    
  3. You can explicitly create "HttpRequest" scope using its tag. Exposed through MatchingScopeLifetimeTags.RequestLifetimeScopeTag property in new versions.

    using (var httpRequestScope = container.BeginLifetimeScope("httpRequest")) // or "AutofacWebRequest" for MVC4/5 integrations
    {
        var repository = httpRequestScope.Resolve<IRepository<Entity>>();
    }
    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top