IServiceCollection
にインスタンスを登録した後、このメソッド呼び出しの前に登録されたIAutomapperProvider
に依存するIAssemblyProvider
を登録する必要があります
_public static IServiceCollection RegisterAutomapperConfiguration(this IServiceCollection container, ServiceLifetime lifeTime = ServiceLifetime.Scoped)
{
//creating the provider to get the IAssemblyProvider for my IAutomapperProvider
var prov = container.BuildServiceProvider();
var assemblyProvider = prov.GetService<IAssemblyProvider>();
container.Register<IAutomapperProvider>(aProv => new AutomapperProvider(assemblyProvider), lifeTime);
var autoMapperProvider = prov.GetService<IAutomapperProvider>();
var mapperConfig = autoMapperProvider.GetMapperConfiguration();
...
}
_
container.Register<IAutomapperProvider>(aProv => new AutomapperProvider(assemblyProvider), lifeTime);
を呼び出した直後に、BuildServiceProviderを再度呼び出さないと、以前に登録したIAutomapperProviderを取得できません。
_public static IServiceCollection RegisterAutomapperConfiguration(this IServiceCollection container, ServiceLifetime lifeTime = ServiceLifetime.Scoped)
{
//creating the provider to get the IAssemblyProvider for my IAutomapperProvider
var prov = container.BuildServiceProvider();
var assemblyProvider = prov.GetService<IAssemblyProvider>();
container.Register<IAutomapperProvider>(aProv => new AutomapperProvider(assemblyProvider), lifeTime);
prov = container.BuildServiceProvider();
var autoMapperProvider = prov.GetService<IAutomapperProvider>();
var mapperConfig = autoMapperProvider.GetMapperConfiguration();
...
}
_
AspNetCoreコードでは、BuildServiceProvider拡張メソッドを呼び出すと、同じIServiceCollectionが使用され、要素を追加することで時間の経過とともに変化する可能性があります。最後に、同じ参照をポイントします。
_public static ServiceProvider BuildServiceProvider(this IServiceCollection services)
{
return BuildServiceProvider(services, ServiceProviderOptions.Default);
}
_
それでは、サービスを解決する方法を知っている新しいインスタンスを取得するために、もう一度呼び出す必要があるのはなぜですか?
混乱を避けるために、Registerメソッドは私が作成した拡張機能ですが、内部的にAddSinglentonまたはAdd ...を呼び出します。
_ public static IServiceCollection Register<TService>(this IServiceCollection container, Func<IServiceProvider, TService> implementationFactory, ServiceLifetime lifeTime)
where TService : class
{
if (container == null)
throw new ArgumentNullException(nameof(container));
if (implementationFactory == null)
throw new ArgumentNullException(nameof(implementationFactory));
switch (lifeTime)
{
case ServiceLifetime.Scoped:
container.AddScoped(typeof(TService), (Func<IServiceProvider, object>)implementationFactory);
break;
case ServiceLifetime.Transient:
container.AddTransient(typeof(TService), (Func<IServiceProvider, object>)implementationFactory);
break;
default:// ServiceLifetime.Singleton
container.AddSingleton(typeof(TService), (Func<IServiceProvider, object>)implementationFactory);
break;
}
return container;
}
_
私もこれに気づきました。クラスのサービスを解決する必要がありますが、クラスのコンシューマーに事前に追加のサービスを登録させている可能性があります。最初はすでにBuildServiceProvider
に電話しました。
問題は、BuildServiceProvider
がIServiceCollection
の拡張メソッドとして呼び出されており、そうすると新しいServiceProvider
が作成されることです。
IServiceCollection
は実際にはIEnumerable<ServiceDescriptor>
したがって、ServiceProvider
が作成された時点での現在のコレクションが何であれ、消費者はServiceProvider
のそのインスタンスにアクセスしたときに表示されます。
したがって、実際にはIServiceCollection
の同じインスタンスにアクセスしているわけではありません。