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

这是我的界面

public interface IMatchServices
{
    string MatchList();
}

在这里上课

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

        return "test";
    }
}

调节器

public class SearchController : Controller
{
    private readonly IMatchServices matchservices;

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

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

        return matchservices.MatchList();
    }
}

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

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

另外,你有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.

换句话说,您还会以错误的顺序排列这些行:

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

相关文章

本文将从上往下,循序渐进的介绍一系列相关.NET的概念,先从...
基于 .NET 的一个全新的、好用的 PHP SDK + Runtime: Pe...
.NET 异步工作原理介绍。
引子 .NET 6 开始初步引入 PGO。PGO 即 Profile Guided Opti...
前言 2021/4/8 .NET 6 Preview 3 发布,这个版本的改进大多来...
前言 开头防杠:.NET 的基础库、语言、运行时团队从来都是相...