いくつかのアプローチがありますが、いくつかは単純にクラス間を移動するコードですs;
1.か「の問題を移動」:下記の2番目のオプションとして、私が説明するように、私はあなたがAssembly Scanning
検討し提案する拡張メソッド
初期オプションは、サービスの設定にextension methods
を使用することです。ここ
がhere見出すことができるASP.Net MVC Bolierplateテンプレートから採取した1つの延長方法、に複数のサービスreigstrationsをラップ一例である。
public static IServiceCollection AddCustomServices(this IServiceCollection services)
{
services.AddScoped<IBrowserConfigService, BrowserConfigService>();
services.AddScoped<IManifestService, ManifestService>();
services.AddScoped<IRobotsService, RobotsService>();
services.AddScoped<ISitemapService, SitemapService>();
services.AddScoped<ISitemapPingerService, SitemapPingerService>();
// Add your own custom services here e.g.
// Singleton - Only one instance is ever created and returned.
services.AddSingleton<IExampleService, ExampleService>();
// Scoped - A new instance is created and returned for each request/response cycle.
services.AddScoped<IExampleService, ExampleService>();
// Transient - A new instance is created and returned each time.
services.AddTransient<IExampleService, ExampleService>();
return services;
}
これはConfigureServices
内で呼び出すことができます。
services.AddCustomServices();
注:特定の構成(たとえば、サービスに複数のオプションを渡す必要がある場合など)では、これはビルダーパターンとして役立ちます)、ハンドコーディングで複数のサービスを登録しなければならないという問題を解決することはできません。基本的には同じコードを別のクラスファイルに書くことと変わりはなく、依然として手動によるメンテナンスが必要です。
2.「問題を解決する」:ASSEMBLYのSCANNING
は、「ベストプラクティス」オプションは自動的にImplemented Interfaces
に基づいて部品を検索し、登録するために使用されているAssembly Scanningです。以下Autofac例である:
var assembly= Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
寿命(または範囲)を処理するための1つのトリック登録、例えばIScopedService
ため、マーカーインターフェース(空のインタフェース)を使用して、スキャン・サービスを登録するためにそれを使用することです適切な生涯でこれは複数のサービスを登録するための最も摩擦の少ない手法であり、自動であり、したがって「ゼロ保守」です。
注:組み込みのASP.Net Core DI実装では、Assembly Scanning
はサポートされていません。
概要
var collection = new ServiceCollection();
collection.Scan(scan => scan
.FromAssemblyOf<ITransientService>()
.AddClasses(classes => classes.AssignableTo<ITransientService>())
.AsImplementedInterfaces()
.WithTransientLifetime()
.AddClasses(classes => classes.AssignableTo<IScopedService>())
.As<IScopedService>()
.WithScopedLifetime());
:Extension Methods
(該当する場合)との組み合わせで
Assembly Scanning
は、保存されますが、GitHubの(およびNuget)のScrutorプロジェクトは、この機能を追加し、へのサービスおよびType登録を凝縮しますかなりの量のメンテナンスを行い、アプリケーションの起動時に一度実行され、その後キャッシュされます。コードサービス登録を手渡す必要がなくなります。
public static void AddScopedFromAssembly(this IServiceCollection services, Assembly assembly)
{
var allServices = assembly.GetTypes().Where(p =>
p.GetTypeInfo().IsClass &&
!p.GetTypeInfo().IsAbstract);
foreach (var type in allServices)
{
var allInterfaces = type.GetInterfaces();
var mainInterfaces = allInterfaces.Except
(allInterfaces.SelectMany(t => t.GetInterfaces()));
foreach (var itype in mainInterfaces)
{
services.AddScoped(itype, type); // if you want you can pass lifetime as a parameter
}
}
}
と使用方法:
私は拡張メソッドを知っていますが、拡張メソッドごとに1行のコードでたくさんのものを追加するIServiceCollectionの拡張メソッドを書くことができます –
私は拡張メソッドを知っています。しかし、例えばあなたは答えを書くことができますか? –
登録グループに対して「抽出メソッド」リファクタリングを適用するとどうなりますか?後でこれらのメソッドを他のクラスに移動することもできます。 – Steven