调用单例服务有什么区别。
在app.UseMvc();
app.UseMvc(options =>
{
options
.ServiceProvider
.GetRequiredService<IYamlIndexer>()
.IndexContentFiles(Constants.ContentPath);
});
或者这个:
app
.ApplicationServices
.GetRequiredService<IYamlIndexer>()
.IndexContentFiles(Constants.ContentPath);
答案 0 :(得分:1)
在大多数情况下,两者之间没有区别。这两个属性都指向相同的IServiceProvider
实例,并且都将获得必需的单例服务的相同实例。在边缘情况下,调用的时间可能会有所不同,但我想不到会导致这种情况发生的边缘情况。除非我们做一些不寻常的事情,否则两者都将只运行一次,并且只能在应用程序启动期间运行。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<SomeSingltonService>();
}
public void Configure(IApplicationBuilder app)
{
var appServices = app.ApplicationServices;
var appService = appServices.GetRequiredService<SomeSingltonService>();
Console.WriteLine("=======================");
Console.WriteLine("Configure");
app.UseMvc(configureRoutes =>
{
var routeServices = routeBuilder.ServiceProvider;
var routeService = routeServices.GetRequiredService<SomeSingltonService>();
Console.WriteLine("UseMvc");
if (appServices == routeServices && appService == routeService)
{
Console.WriteLine("They are the same instances.");
}
});
Console.WriteLine("=======================");
}
}
这是输出:
=======================
Configure
UseMvc
They are the same instance.
=======================
UseMvc
在后台将IApplicationBulder
传递给RouteBuilder
构造函数。然后RouteBuilder
将IApplicationBulder.ApplicationServices
分配给它自己的IRouteBuilder.ServiceProvider
属性。
来自MvcApplicationBuilderExtensions.cs的代码
public static IApplicationBuilder UseMvc(
this IApplicationBuilder app,
Action<IRouteBuilder> configureRoutes)
{
// ...
var routes = new RouteBuilder(app) // ln 136
{
DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
};
configureRoutes(routes);
// ...
}
来自RouteBuilder.cs的代码
public RouteBuilder(IApplicationBuilder applicationBuilder, IRouter defaultHandler)
{
// ...
ServiceProvider = applicationBuilder.ApplicationServices; // ln 36
// ...
}
答案 1 :(得分:0)
在(2)中,IndexContentFiles
将在应用程序启动期间立即启动,而应用程序未“完全运行”。这可能会导致一些问题(取决于IYamlIndexer.IndexContentFiles实际执行的操作)。另外,如果这是同步长时间运行的呼叫-您的应用在启动过程中会变慢。
在(1)中,该方法将在MVC子系统要求它提供选项的某个时间开始。这将在应用启动后的某个地方发生,如果长时间运行,则将再次花费一些时间...
还有一个问题,您应该问自己-选项如何配置-单例或瞬态(以及为什么您信任此知识)?在最坏的情况下,每次请求“ MVC选项”时,您的IndexContentFiles
都会被调用,并且您的应用将在每次用户请求时调用IndexContentFiles消失...
也许您需要类似IApplicationLifetime的东西吗?