.NET Core 2.0 Autofac Register Class InstancePerRequest doesn't work

情到浓时终转凉″ 提交于 2020-04-10 08:17:52

问题


Here is my interface

public interface IMatchServices
{
    string MatchList();
}

and class here

public class MatchServices : IMatchServices
{
    public string MatchList() {

        return "test";
    }
}

Controller

public class SearchController : Controller
{
    private readonly IMatchServices matchservices;

    public SearchController(IMatchServices matchservices)
    {
        this.matchservices = matchservices;
    }

    [Route("matchlist")]
    public string MatchList() {

        return matchservices.MatchList();
    }
}

and ConfigureService

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<MatchServices>().As<IMatchServices>().SingleInstance();
    builder.Populate(services);
    var container = builder.Build();
    return container.Resolve<IServiceProvider>();
}

And Finally The Error (When I register with InstancePerRequest):

Autofac.Core.DependencyResolutionException: Unable to resolve the type 'xxx.Services.MatchServices' because the lifetime scope it belongs in can't be located. The following services are exposed by this registration: - xxx.Interfaces.IMatchServices

Details ---> No scope with a tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested.

If you see this during execution of a web application, it 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 dependency resolver or the request lifetime scope, never from the container itself. (See inner exception for details.) ---> Autofac.Core.DependencyResolutionException: No scope with a tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested.

When I register MatchServices class SingleInstance it is working but InstancePerRequest didn't work. Why? I didn't even do any DI in MatchServices.


回答1:


As per the Autofac documentation:

Use InstancePerLifetimeScope instead of InstancePerRequest. In previous ASP.NET integration you could register a dependency as InstancePerRequest which would ensure only one instance of the dependency would be created per HTTP request. This worked because Autofac was in charge of setting up the per-request lifetime scope. With the introduction of Microsoft.Extensions.DependencyInjection, the creation of per-request and other child lifetime scopes is now part of the conforming container provided by the framework, so all child lifetime scopes are treated equally - there’s no special “request level scope” anymore. Instead of registering your dependencies InstancePerRequest, use InstancePerLifetimeScope and you should get the same behavior. Note if you are creating your own lifetime scopes during web requests, you will get a new instance in these child scopes.

Also, you have another issue:

Note that Populate is basically a foreach to add things into Autofac that are in the collection. If you register things in Autofac BEFORE Populate then the stuff in the ServiceCollection can override those things; if you register AFTER Populate those registrations can override things in the ServiceCollection. Mix and match as needed.

In other words, you also have these lines in the wrong order:

builder.Populate(services);
builder.RegisterType<MatchServices>().As<IMatchServices>().InstancePerLifetimeScope();


来源:https://stackoverflow.com/questions/48705473/net-core-2-0-autofac-register-class-instanceperrequest-doesnt-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!