如何将并行依赖项注入到AspNetCore ICollection服务中?

时间:2018-07-31 14:47:17

标签: c# asp.net-core dependency-injection task-parallel-library

目前,我已将所有注入的依赖项放入我的ConfigureServices

 public void ConfigureServices(IServiceCollection services)
 {
     services.AddSingleton<IConfiguration>(Configuration);
     //injecting my dependenies here
     services.AddDependencies(Configuration);
 }

问题是我想优化下面并行注入事物的过程。请注意,我要优化的是此方法的处理时间 AddDependencies

public static IServiceCollection AddDependencies(this IServiceCollection services, IConfiguration configuration)
{
  services.RegisterTypes(configuration)
            .AddFluentValidationConfiguration()
            .AddAutomapperConfiguration();

  return services;
}

起初我的方法是:

public static IServiceCollection AddDependencies(this IServiceCollection services, IConfiguration configuration)
    {
        var t1 = Task.Run(() => { services.RegisterTypes(configuration);});
        var t2 = Task.Run(() => { services.RegisterFluentValidation();});
        var t3 = Task.Run(() => { services.RegisterMappingsWithAutomapper();});

        Task.WhenAll(t1, t2, t3).Wait();

        return services;
    }

但是有时我会遇到异常,诸如RegisterTypes之类的方法会在内部进行此类调用

services.Register<ISmtpConfig, SmtpConfig>(lifeTime);

因此资源services在多个线程之间共享,我认为放置类似于此的lock语句可以解决问题,但是没有

 private Object thisLock = new Object(); --> global variable  

 lock (thisLock)  
 {  
   services.Register<ISmtpConfig, SmtpConfig>(lifeTime);
 }

有人可以把我放在正确的位置吗?

2 个答案:

答案 0 :(得分:0)

我很确定这不是您可以通过并行添加依赖项来改进某些地方的地方。 实际上,此配置方法在应用程序启动时运行一次。在我的示例项目中(在Visual Studio中为“调试”模式),该过程不到一秒钟。在第二次运行时(仅确保已将其准时)为6ms。 VS大大降低了性能(700ms相对于首次运行300ms)。 因此,我建议您将秒表放入ConfigureServices()方法的开头,并输入类似

stopwatch.Stop();
Console.WriteLine($"Service initialization took {stopwatch.ElapsedMilliseconds} ms");

最后。

也许您可以提供有关性能问题的更多线索?

答案 1 :(得分:0)

我认为性能问题是:开始时需要加载许多类,并且所有类都来自不同的程序集,这将迫使Web服务器将它们加载到内存中。但应按需注册和加载它们,您可以按照此帖子实施: C# Dependency Injection Runtime (dynamic) registration