.Net Core公式DIフレームワーク
6022 ワード
NetCoreは方法のDIフレームワークを提供し,AspNetCoreでこの注入フレームワークを大量に使用した.拡張パッケージとして提供するもので、使用時にはNugetパッケージでMicrosoft.Extensions.DependencyInjectionで使用します.他のDIフレームワークと比較して軽量であり、コンストラクタ注入のみをサポートし、属性注入、およびメソッド注入はサポートされていない.
使用は簡単ですが、一般的な手順は次のとおりです.
サービスの登録方法
サービスには一般的に以下の方法があります. serviceCollection.Add(ServiceDescriptor item) serviceCollection.AddXXX() serviceCollection.AddXXX(Func implementationFactory)
次の文は同じです.
サービスプロバイダサービスプロバイダ
サービスインスタンスの作成、破棄はServiceProviderが管理します.生成されたサービスインスタンスは、サービスインスタンスが他の場所で使用される可能性があるため、オブジェクトのDisposeメソッドを実行しないのが一般的です.
ServiceProviderを解放すると、生成されたオブジェクトが解放されます.
インスタンスを生成するとき、オブジェクトがDisposeインタフェースを実装すると、そのオブジェクトは_に保存されます.disposablesリストでは、Providerが解放されると自動的に_が呼び出されます.disposables要素オブジェクトのDisposeメソッド
ServiceProvider自体が新しいServiceProviderを作成することで、役割ドメインScopeが生成されます.
サービスのライフサイクル
ライフサイクルは3つに分けられます.過渡Transient:サービスプロバイダから取得するたびに、新しいインスタンスが返されます. 役割ドメインScope:同じ役割ドメインで生成するインスタンスは同じ、すなわち同じServiceProviderで取得したインスタンスは同じ である.単例Singleton:いずれかのServiceProviderで取得した例は同じ である.
役割ドメインは、主に特定のServiceProvider、すなわち同一のServiceProviderの下でScopeタイプとして登録されているオブジェクトが一例である
例
インスタンスオブジェクトの説明 IFOoがTransientに登録するとfoo foo 2,foo 3はいずれも を待たない. IBarがScopeとして登録されている場合、bar=bar 2(同じrootProviderで提供されているため)、bar 2<>bar 2(異なるProviderで提供されているため、1つはrootProviderで、1つはchildProviderであるため) IoobarはSingletonに登録されているのでfoobar==foobar 2==foobar 3 インスタンスの解放タイミングが【実行ポイント1】まで実行された場合、解放: childProvider自体は、childProviderが作成したbar 3、foo 3 を再解放する. bar3 foo3
が【実行ポイント2】まで実行された場合、解放: rootProvider自体 foo foo2 bar、(bar 2はありません.bar 2はbarですから) childProvider 2、およびchildProvider 2によって作成するfoo 3
ASP.Net Coreでの使用
asp.Netcoreには主に2つのServiceProviderがあり、対応するサービスインスタンスを手動で取得できます. WebHostのServiceProvider、すなわちwebHost.Services Http要求におけるHttpContextのServiceProvider、すなわちHttpContext.RequestServices
これらの関係は親子関係である:Http要求におけるServiceProviderは、WebHostのServiceProviderに従ってミドルウェア
Httpリクエストが終了すると、HttpリクエストのServiceProviderが解放され、その役割ドメインのインスタンスオブジェクトが解放されます.
ちゅうにゅうモード
他の3番目に成熟したIocフレームワークを使用する(推奨しない)
公式DIフレームワークは他の成熟したIocフレームワークに取って代わることができるが、NetCore DIフレームワークは「パッケージング」として、他のDIフレームワーク(例えばAutofac、Unityなど)を挿入して他のDIフレームワークを挿入する目的で、主に他のフレームワークのいくつかの利点、例えば一括登録、属性注入などを利用したいと考えています.
置き換えの方法は,主にサービスメソッドConfigureServicesを再登録する際に,サードパーティDI拡張実装のIServiceProviderで公式DIのIServiceProviderを置き換えている.
現在、公式DI拡張を実現しているサードパーティ製フレームワークは、AspectCore、Autofac、Unityであり、サードパーティ製DIフレームワークの使用は若干の利便性をもたらしているが、サードパーティ製DI容器の特性への依存性をもたらしている
Asp.NetCoreでのAutofacの使用
使用は簡単ですが、一般的な手順は次のとおりです.
// 1.
var serviceCollection = new ServiceCollection();
.AddSingleton()
.AddTransient()
.BuildServiceProvider())
// 2.
ServiceProvider serviceProvider serviceCollection.BuildServiceProvider();
// 3. Provider.GetService()
var IFoo = serviceProvider.GetService();
サービスの登録方法
サービスには一般的に以下の方法があります.
次の文は同じです.
serviceCollection.AddTransient();
serviceCollection.Add(new ServiceDescriptor(typeof(IFoo),typeof(Foo), ServiceLifetime.Transient));
serviceCollection.AddTransient(provider => new Foo());
サービスプロバイダサービスプロバイダ
サービスインスタンスの作成、破棄はServiceProviderが管理します.生成されたサービスインスタンスは、サービスインスタンスが他の場所で使用される可能性があるため、オブジェクトのDisposeメソッドを実行しないのが一般的です.
ServiceProviderを解放すると、生成されたオブジェクトが解放されます.
インスタンスを生成するとき、オブジェクトがDisposeインタフェースを実装すると、そのオブジェクトは_に保存されます.disposablesリストでは、Providerが解放されると自動的に_が呼び出されます.disposables要素オブジェクトのDisposeメソッド
ServiceProvider自体が新しいServiceProviderを作成することで、役割ドメインScopeが生成されます.
サービスのライフサイクル
ライフサイクルは3つに分けられます.
役割ドメインは、主に特定のServiceProvider、すなわち同一のServiceProviderの下でScopeタイプとして登録されているオブジェクトが一例である
例
using (ServiceProvider rootProvider = new ServiceCollection()
.AddTransient()
.AddScope()
.AddSingleton()
.BuildServiceProvider())
{
IFoo foo = rootProvider.GetService();
IFoo foo2 = rootProvider.GetService();
IBar bar = rootProvider.GetService();
IBar bar2 = rootProvider.GetService();
IFoobar foobar = rootProvider.GetService();
IFoobar foobar2 = rootProvider.GetService();
IFoo foo3 = null;
IBar bar3 = null;
IFoobar foobar3 = null;
using(var scope = rootProvider.CreateScope())
{
var childProvider = scope.ServiceProvider;
foo3 = childProvider.GetService();
bar3 = childProvider.GetService();
foobar3 = childProvider.GetService();
}
var childProvider2 = rootProvider.CreateScope().ServiceProvider;
IFoo foo3 = childProvider2.GetService();
// 1
}
// 2
インスタンスオブジェクトの説明
ASP.Net Coreでの使用
asp.Netcoreには主に2つのServiceProviderがあり、対応するサービスインスタンスを手動で取得できます.
これらの関係は親子関係である:Http要求におけるServiceProviderは、WebHostのServiceProviderに従ってミドルウェア
RequestServicesContainerMiddleware
によって生成される.Httpリクエストが終了すると、HttpリクエストのServiceProviderが解放され、その役割ドメインのインスタンスオブジェクトが解放されます.
ちゅうにゅうモード
public class SampleController ControllerBase
{
// 1. :
private IService _service = null;
public SampleController(IService service)
{
this._service = service;
}
// 2. :
[HttpPost]
public IActionResult Method1([FromServices] IService service) => service.DoSomething()
// 3. : HttpContext,
[HttpGet]
public IActionResult Method2()
{
IService service = HttpContext.RequestServices.GetService<>(IService);
...
}
...
}
他の3番目に成熟したIocフレームワークを使用する(推奨しない)
公式DIフレームワークは他の成熟したIocフレームワークに取って代わることができるが、NetCore DIフレームワークは「パッケージング」として、他のDIフレームワーク(例えばAutofac、Unityなど)を挿入して他のDIフレームワークを挿入する目的で、主に他のフレームワークのいくつかの利点、例えば一括登録、属性注入などを利用したいと考えています.
置き換えの方法は,主にサービスメソッドConfigureServicesを再登録する際に,サードパーティDI拡張実装のIServiceProviderで公式DIのIServiceProviderを置き換えている.
現在、公式DI拡張を実現しているサードパーティ製フレームワークは、AspectCore、Autofac、Unityであり、サードパーティ製DIフレームワークの使用は若干の利便性をもたらしているが、サードパーティ製DI容器の特性への依存性をもたらしている
Asp.NetCoreでのAutofacの使用
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry(Configuration);
services.AddMvc();
return RegisterAutofac(services);
}
private IServiceProvider RegisterAutofac(IServiceCollection services)
{
var builder = new ContainerBuilder();
builder.Populate(services);
var assembly = this.GetType().GetTypeInfo().Assembly;
builder.RegisterType();
builder.RegisterAssemblyTypes(assembly)
.Where(type =>
typeof(IDependency).IsAssignableFrom(type) && !type.GetTypeInfo().IsAbstract)
.AsImplementedInterfaces()
.InstancePerLifetimeScope().EnableInterfaceInterceptors().InterceptedBy(typeof(AopInterceptor));
this.ApplicationContainer = builder.Build();
return new AutofacServiceProvider(this.ApplicationContainer);
}