【发布时间】:2019-08-27 08:07:30
【问题描述】:
下面是示例代码:
// startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ConcreteA>;
services.AddScoped<ConcreteB>;
services.AddScoped<ConcreteBDependency>;
}
public void Configure(IApplicationBuilder app) {
app.UseStatusCodePages();
app.UseDeveloperExceptionPage();
app.UseMvcWithDefaultRoute();
ConcreteA.Run(app.ApplicationServices);
}
_____________________________________________________
public class ConcreteA
{
public static Run(IServiceProvider serviceProvider)
{
ConcreteB _concreteB = serviceProvider.GetRequiredService<ConcreteB>();
...
}
}
public class ConcreteB
{
private ConcreteBDependency _dependency ;
public ConcreteB(ConcreteBDependency denpendency)
{
_dependency = denpendency
}
}
我问了很多关于服务范围的问题,我认为这个问题将是最后一块拼图:
以下是我的问题:
Q1-_concreteB是在DI容器的根作用域下创建的吗?
Q2-由于ConcreteB 具有ConcreteBDependency 的依赖关系,ConcreteBDependency 的实例(假设它在内部称为_dependency)之前_concreteB 是通过serviceProvider.GetRequiredService<ConcreteB>(); 创建的,@987654329 也是如此@也在DI容器的根作用域下创建?
Q3-如果_concreteB和_dependency都创建在DI容器的根作用域下,我们是否需要禁用program.cs中的作用域验证检查为
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseDefaultServiceProvider(options =>
options.ValidateScopes = false)
.Build();
【问题讨论】:
-
serviceProviderinConcreteA.Run是与app.ApplicationServices相同的对象,因此您只是针对同一个服务提供者实例调用.GetRequiredService,尽管在不同的位置。对于 .NET,调用方法时没有区别。 -
@John 和
_concreteB和_dependency都是在 DI 容器的根范围下创建的, -
不清楚你在说什么。什么是“根范围”?有一种基本上“没有范围”的情况,这将是最接近“根”的东西,但这只是具有单例生命周期的对象。所有其他对象都在 some 范围内创建。
-
对于具有“范围”生命周期的服务,这通常等同于 ASP.NET Core 中的请求,即它们存在于接收请求和最终响应该请求之间发送。在此期间,在单个请求的上下文中,无论注入多少次,实例都是相同的。
标签: c# dependency-injection asp.net-core-mvc