.NET Core 2.0 Autofac注册类InstancePerRequest不起作用

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

这是我的界面

1
2
3
4
public interface IMatchServices
{
    string MatchList();
}

在这里上课

1
2
3
4
5
6
7
public class MatchServices : IMatchServices
{
    public string MatchList() {

        return"test";
    }
}

控制者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SearchController : Controller
{
    private readonly IMatchServices matchservices;

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

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

        return matchservices.MatchList();
    }
}

ConfigureService

1
2
3
4
5
6
7
8
9
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>();
}

最后是错误(当我向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.

当我注册MatchServices类SingleInstance时,它可以工作,但InstancePerRequest却不起作用。 为什么? 我什至在MatchServices中都没有做任何DI。


根据Autofac文档:

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.

另外,您还有另一个问题:

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.

换句话说,这些行的顺序也错误:

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