Autofac cannot resolve class

535 views Asked by At

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.

1

There are 1 answers

1
Cyril Durand On BEST ANSWER

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