![](/img/trans.png)
[英]Dependency injection failed with IAuthorizationFilter and Simple Injector for ASP.NET Core
[英]Simple Injector w/ ASP.Net Core 2.0 IOptionsSnapshot injection
我正在嘗試在錯誤#429中提出的建議,並且遇到了他在該位置報告的錯誤,但是從沒有提供堆棧跟蹤。 我還閱讀並使用了直到最近的有關不使用IOptions
和相關類的指南。 當我們在Azure中運行某些東西時,確實需要IOptionsSnapshot
,並且當我們達到極限時,需要能夠即時打開/關閉選項,並且重啟服務不是選項,因為它最多需要5個最初需要幾分鍾,這是由於我們需要一些第三方產品。
這是我們設置的內容:
接口ISearchSettings
>類SearchSettings
(基本上,這里的所有屬性,除了1個布爾值,我們都可以根據需要單身。一個布爾值有點告訴我們是使用內部搜索還是使用天藍色搜索)
應用啟動時,出現以下錯誤:
System.InvalidOperationException:配置無效。 創建類型為IOptionsSnapshot <SearchSettings>的實例失敗。 類型為IOptionsSnapshot <SearchSettings>的注冊委托引發了異常。 無法從ASP.NET Core請求服務請求服務'IOptionsSnapshot <SearchSettings>。 請確保在活動HTTP請求的上下文中調用此方法。
在“配置服務”中:
services.AddOptions();
services.Configure<ISearchSettings>(
this.Configuration.GetSection("AzureSearchSettings"));
services.Configure<SearchSettings>(
this.Configuration.GetSection("AzureSearchSettings"));
// The next line was added trying some other suggestions from similar
// errors. It didn't resolve the issue
services.AddScoped(
cfg => cfg.GetService<IOptionsSnapshot<SearchSettings>>().Value);
...
services.AddMvc();
...
IntegrateSimpleInjector();
在IntegrateSimpleInjector中:
this.container.Options.DefaultScopedLifestyle =
new AsyncScopedLifestyle();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IControllerActivator>(
new SimpleInjectorControllerActivator(this.container));
services.AddSingleton<IViewComponentActivator>(
new SimpleInjectorViewComponentActivator(this.container));
services.EnableSimpleInjectorCrossWiring(this.container);
services.UseSimpleInjectorAspNetRequestScoping(this.container);
在InitializeContainer中:
// I have tried both Lifestyle Transient and Scoped
this.container.Register<IOptionsSnapshot<SearchSettings>>(
() => app.GetRequestService<IOptionsSnapshot<SearchSettings>>(),
Lifestyle.Transient);
...
this.container.AutoCrossWireAspNetComponents(app);
堆棧跟蹤:
at SimpleInjector.SimpleInjectorAspNetCoreIntegrationExtensions.GetRequestServiceProvider(IApplicationBuilder builder, Type serviceType)
at SimpleInjector.SimpleInjectorAspNetCoreIntegrationExtensions.GetRequestService[T](IApplicationBuilder builder)
at QuotingService.Startup.<>c__DisplayClass9_0.<InitializeContainer>b__0() in E:\Repos\QuotingService\QuotingService\Startup.cs:line 299
at lambda_method(Closure )
at SimpleInjector.InstanceProducer.BuildAndReplaceInstanceCreatorAndCreateFirstInstance()
at SimpleInjector.InstanceProducer.GetInstance()
--- End of inner exception stack trace ---
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.InstanceProducer.VerifyInstanceCreation()
--- End of inner exception stack trace ---
at SimpleInjector.InstanceProducer.VerifyInstanceCreation()
at SimpleInjector.Container.VerifyInstanceCreation(InstanceProducer[] producersToVerify)
at SimpleInjector.Container.VerifyInternal(Boolean suppressLifestyleMismatchVerification)
at SimpleInjector.Container.Verify()
at QuotingService.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime) in E:\Repos\QuotingService\QuotingService\Startup.cs:line 229
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
關於什么需要更改才能使此工作有任何想法?
感謝您提供的出色產品以及所提供的任何幫助。
您應該避免在簡單的Injector注冊的委托中調用GetRequestService
,因為這種調用要求存在一個活動的HTTP請求,該請求在應用程序啟動期間將不可用。
而是依靠AutoCrossWireAspNetComponents
從ASP.NET Core獲取IOptionsSnapshot<SearchSettings>
。
但是,要使其正常工作,您需要調用services.Configure<SearchSettings>
。
這是一個有效的配置:
public class Startup
{
private Container container = new Container();
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json");
this.Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// ASP.NET default stuff here
services.AddMvc();
this.IntegrateSimpleInjector(services);
services.Configure<SearchSettings>(
Configuration.GetSection("SearchSettings"));
}
private void IntegrateSimpleInjector(IServiceCollection services)
{
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IControllerActivator>(
new SimpleInjectorControllerActivator(container));
services.EnableSimpleInjectorCrossWiring(container);
services.UseSimpleInjectorAspNetRequestScoping(container);
}
public void Configure(IApplicationBuilder app)
{
container.AutoCrossWireAspNetComponents(app);
container.RegisterMvcControllers(app);
container.Verify();
// ASP.NET default stuff here
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
使用此配置,您可以在所有位置注入IOptionsSnapshot<T>
。 例如在您的HomeController
內部:
public class HomeController : Controller
{
private readonly IOptionsSnapshot<SearchSettings> snapshot;
public HomeController(
IOptionsSnapshot<SearchSettings> snapshot)
{
this.snapshot = snapshot;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.