0

I'm building an application with ASP.Net MVC for the back-end. Autofac is being used for dependency injection. Several components/classes are registered as InstancePerRequest. The Entity Framework context and unit of work (just a wrapper that calls context.SaveChanges()) are registered as InstancePerLifetimeScope. Example code:

builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(DomainModule)))
    .Where(t => t.IsClosedTypeOf(typeof(IFooService<>)))
    .AsImplementedInterfaces()
    .AsClosedTypesOf(typeof(IFoo<>))
    .InstancePerRequest();

builder.RegisterType<FooContext>()
    .AsSelf()
    .As<IObjectContextAdapter>()
    .InstancePerLifetimeScope();

builder.RegisterType<UnitOfWork>()
    .AsImplementedInterfaces()
    .AsSelf()
    .InstancePerLifetimeScope();

Resolving a class from the container using an explicit scope throws the following exception:

{"No scope with a Tag matching 'AutofacWebRequest' is visible from the scopein which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself."}

Code that triggers the above exception:

using (var scope = _lifetimeScope.BeginLifetimeScope())
{
    var authOrchestration = scope.Resolve<IAuthOrchestration>();
    apiClient = authOrchestration.GetApiClient(context.ClientId);
}

Note that the IAuthOrchestration isn't being registered with things like InstancePerRequest, so that one should just default to InstancePerDependency.

I've been trying to wrap my head around this for a couple hours now. I've read these two articles. From what I've read, I guess the exception is being thrown due to the scopes that do not match (as described here). If someone would be able to explain why I get this error, I'd be very thankful.

Many thanks in advance.

Kaj Nelissen
  • 915
  • 10
  • 29
  • Does your `IAuthOrchestration` implementation depends on `IFoo<>` ? – Cyril Durand Jun 10 '15 at 12:12
  • @CyrilDurand Orchestration like the mentioned ``IAuthOrchestration`` depend on services like the ``IFooService`` (renamed that one in the question for clarity). These services depend on repositories and these repositories ultimately depend on the ``FooContext``. – Kaj Nelissen Jun 10 '15 at 12:19
  • You cannot begin a new scope like that with InstancePerRequest. The answer in this question should work for you: http://stackoverflow.com/questions/10027330/how-to-resolve-autofac-instanceperhttprequest – Rob Tillie Jun 10 '15 at 12:29
  • @RobTillie Yeah, had to pass the tag along. So both``AutofacWebRequest`` and ``MatchingScopeLifetimeTags.RequestLifetimeScopeTag`` do the trick. – Kaj Nelissen Jun 10 '15 at 13:20

1 Answers1

0

IAuthOrchestration has an indirect dependency on IFoo which is registered as InstancePerHttpRequest. To resolve (directly or indirectly) a IFoo you have to use a request ILifetimeScope

You create a ILifetimeScope which is not a RequestLifetimeScope. To create such ILifetimeScope, you can use the MatchingScopeLifetimeTags.RequestLifetimeScope` tag.

using (var scope = _lifetimeScope
                    .BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag))
{
    var authOrchestration = scope.Resolve<IAuthOrchestration>();
    apiClient = authOrchestration.GetApiClient(context.ClientId);                
}
Cyril Durand
  • 15,834
  • 5
  • 54
  • 62