C# 有没有一种方法可以预构建我在Simple Injector容器中注册的所有服务?
在部署或IIS管理器重新启动后,我正试图缩短服务器的初始请求时间。当我在寻找一种方法来做到这一点时,我偶然发现了这篇文章。然而,我的项目使用(SI)库-我不确定如何(如果可能的话)指示SI预构建我的注册服务,这将提高第一次请求的时间 以前有人试过吗 这是我的C# 有没有一种方法可以预构建我在Simple Injector容器中注册的所有服务?,c#,asp.net-core,simple-injector,C#,Asp.net Core,Simple Injector,在部署或IIS管理器重新启动后,我正试图缩短服务器的初始请求时间。当我在寻找一种方法来做到这一点时,我偶然发现了这篇文章。然而,我的项目使用(SI)库-我不确定如何(如果可能的话)指示SI预构建我的注册服务,这将提高第一次请求的时间 以前有人试过吗 这是我的Startup.cs public class Startup { private IHostingEnvironment _env; private static readonly Container _container
Startup.cs
public class Startup
{
private IHostingEnvironment _env;
private static readonly Container _container = new Container();
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddSession();
services.Configure<AzureBlobSettings>(settings =>
Configuration.GetSection("AzureBlobSettings").Bind(settings));
IntegrateSimpleInjector(services);
}
private void IntegrateSimpleInjector(IServiceCollection services)
{
_container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IControllerActivator>(
new SimpleInjectorControllerActivator(_container));
services.AddSingleton<IViewComponentActivator>(
new SimpleInjectorViewComponentActivator(_container));
services.EnableSimpleInjectorCrossWiring(_container);
services.UseSimpleInjectorAspNetRequestScoping(_container);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
_env = env;
InitializeContainer(app, env);
// standard config
_container.Verify();
// standard config
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}"
);
routes.MapRoute(
name: "openSpotfire",
template:
"{controller=OpenAnalytics}/{action=AnalyticsView}/{id?}/{name?}"
);
});
}
private void InitializeContainer(
IApplicationBuilder app, IHostingEnvironment env)
{
// Add application presentation components:
_container.RegisterMvcControllers(app);
_container.RegisterMvcViewComponents(app);
// Add application services.
ServiceConfiguration.ConfigureService(_container, Configuration, env);
// Allow Simple Injector to resolve services from ASP.NET Core.
_container.AutoCrossWireAspNetComponents(app);
}
}
public static class ServiceConfiguration
{
public static void ConfigureService(
Container c, IConfiguration configuration, IHostingEnvironment env)
{
//Cross Cutting Concerns from nuget
container.Register<CurrentUser>(Lifestyle.Scoped);
container.Register<IUserProfileService, CachedUserProfileService>(
Lifestyle.Scoped);
container.Register<ISharedItemBuilderFactory, SharedItemBuilderFactory>(
Lifestyle.Scoped);
container.Register<IEmailer, DbMailer>(Lifestyle.Scoped);
container.Register<IRecipientService, RecipientService>(Lifestyle.Scoped);
container.Register<ISpotfireUserDataService, SpotfireUserDataService>(
Lifestyle.Scoped);
container.Register<IWorkbookManagementService, WorkbookManagementService>(
Lifestyle.Scoped);
container.Register<ILogger, NLogLogger>(Lifestyle.Scoped);
// CCC Settings
container.Register(() => new DbMailConnection
{
ConnectionString = configuration["AppSettings:ConnectionString"],
Profile = configuration["AppSettings:DbMailProfile"]
}, Lifestyle.Singleton);
}
}
您链接的文章只是在启动时创建每个服务的一个实例,而不管它是单例的、有范围的还是暂时的 编辑:删除代码,因为有更好的解决方案 [是否可能]指示SI预构建我的注册服务,这将提高首次请求时间 是的,有配置容器后,应调用
容器。验证()
。
除其他事项外,verify将迭代所有已知的注册,创建并编译它们的表达式树
默认情况下,Verify
执行许多操作:
- 它为所有注册构建所有表达式树
- 它将这些表达式树编译为委托
- 它调用这些委托以确保可以创建实例。这样,它强制JIT编译器编译委托
- 它将迭代容器控制的集合,因为它们在简单注入器中表现为流
- 它将确保在decorator包含decorateee工厂的情况下创建decorateee
- 它将在对象图上运行完整诊断
Verify
,允许您取消最后一个诊断步骤。但请注意,您通常不应禁止诊断
除了减少执行前几个请求所需的时间外,还建议调用verify,因为它通过运行诊断服务来检查配置的运行状况。这是将Simple Injector与.NET的所有其他DI容器分开的独特功能
有关更多信息,请参阅上的文档和。有关解决方案的三个注意事项:1。除非将操作包装在活动作用域中,否则此代码可能无法工作。2.当您调用了
container.Verify()
之后,就不再需要执行此循环,因为这是Verify实际执行的操作之一。3.您的解决方案不会编译所有内容,例如,集合仍然是惰性读取的<代码>验证,另一方面,确保注册的集合也将被编译和测试。感谢您纠正我的错误,不敢相信我没有考虑范围位,因为这是在启动代码中,而不是请求中。从未考虑过Verify
呼叫在内部执行的操作,tbh。感谢您的详细回答!我没有意识到,verify
可以做到这一切,实际上,由于方法的名称,我没有想到会这样。我想我应该先检查一下文档中的方法:)将verify()
作为启动例程的固定部分,可以让我们避免很多潜在的麻烦。应该是所有DI容器上的标准功能。请注意,Andrew Lock描述的迭代ServiceCollection的方法很容易崩溃并阻止应用程序启动,因为您会发现框架和第三方注册有时处于部分正确的状态,并根据用户配置完成。ServiceCollection注册不需要正确,这使得迭代ServiceCollection很困难。一开始可能有用,但在更新软件包或添加新软件包后会出现故障。感谢您的建议,Steven!乍一看,Andrew建议的方法似乎是一个非常好的主意,但现在我倾向于不接触我的当前配置:)预构建ServiceCollection:坏主意。预制简单注射器:非常好。