这是我的界面
public interface IMatchServices
{
string MatchList();
}
在这里上课
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();
}
}
和
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 .
最佳答案
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 ofMicrosoft.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 dependenciesInstancePerRequest
, useInstancePerLifetimeScope
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 BEFOREPopulate
then the stuff in theServiceCollection
can override those things; if you register AFTERPopulate
those registrations can override things in theServiceCollection
. Mix and match as needed.
换句话说,这些行的顺序也有误:
builder.Populate(services);
builder.RegisterType<MatchServices>().As<IMatchServices>().InstancePerLifetimeScope();
关于.NET Core 2.0 Autofac 注册类 InstancePerRequest 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48705473/