简体   繁体   中英

MvcSiteMapProvider and Autofac issue with InstancePerRequest

I've installed nutget package MvcSiteMapProvider.MVC5.DI.Autofac.Modules . I'm trying to register my DBContext as InstancePerRequest. This however fails with the error

No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested.

If I change my DBContext to InstancePerLifetimeScope, all is well. The error is thrown in the file

DI\Autofac\Modules\MvcSiteMapProviderModule.cs    Line: 195

Actually, if I try to register any of my own types with InstancePerRequest, I get this error. I'm new to Autofac so don't really understand a lot of the code in the nuget package for MvcSiteMapProvider Autofac. While I'm learning more about Autofac, hoping someone can point in the right direction as to how to get around this issue?

EDIT:

From Autofac docs, I'm getting the error because:

Code is running during application startup (e.g., in an ASP.NET Global.asax) that uses dependency resolution when there isn’t an active request yet.

According to MvcSiteMapProvider docs, this line is required though, so can I move this somewhere else?

// Setup global sitemap loader (required)
MvcSiteMapProvider.SiteMaps.Loader = container.Resolve<ISiteMapLoader>();

EDIT 2:

protected void Application_Start()
{
    // BEGIN: Autofac Config
    var builder = new ContainerBuilder();

    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    builder.RegisterControllers(typeof(MvcApplication).Assembly);
    builder.RegisterSource(new ViewRegistrationSource());

    // Register context and unit of work here
    IoC.Dependencies.Register.RegisterTypes(builder);

    builder.RegisterModule(new MvcSiteMapProviderModule());
    builder.RegisterModule(new MvcModule());

    var container = builder.Build();

    MvcSiteMapProvider.SiteMaps.Loader = container.Resolve<ISiteMapLoader>();

    GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    // END: Autofac Config

    Helpers.Log4NetManager.InitializeLog4Net();
    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);


    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}

You are registering your controllers twice with Autofac.

// This registers the all of the controllers in the application
builder.RegisterControllers(typeof(MvcApplication).Assembly);

// And so does this...
builder.RegisterModule(new MvcModule());

Contents of MvcModule :

public class MvcModule
    : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        var currentAssembly = typeof(MvcModule).Assembly;

        builder.RegisterAssemblyTypes(currentAssembly)
            .Where(t => typeof(IController).IsAssignableFrom(t))
            .AsImplementedInterfaces()
            .AsSelf()
            .InstancePerDependency();
    }
}

UPDATE

From here :

The error pretty much says it all - something in your registrations has a dependency that is registered as InstancePerRequest and it's being resolved outside of a web request.


I am not sure that registering DBContext as InstancePerRequest is such a good idea. MvcSiteMapProvider loads before any request context is created, so if you are using dynamic node providers or custom ISiteMapNodeProvider implementations that access the database, it isn't going to work. A better choice would be to use InstancePerDependency which is not dependent upon HttpContext .

Instance Per Dependency

Also called 'transient' or 'factory' in other containers. Using per-dependency scope, a unique instance will be returned from each request for a service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM