フレームワークの構造は次のとおりです。
- webapi プロジェクト
- 基本的な CQRS プロジェクト
- Nhibnerate 構成プロジェクト
このソリューションでは、Autofac を使用してすべてのクラスを接続します。API はすべてのアセンブリを読み込み、それらのアセンブリにすべてのモジュールを登録します。
ほとんどのモジュールは、すべてのインターフェースと実装を単純に探します。これは、リクエストごとにインスタンスを使用してうまく機能します。
CQRS は、コマンドおよびクエリ ハンドラーの非常に基本的な例です。将来的には多くのものがあり、さまざまな依存関係がある可能性があるため、すべてのハンドラーを取得する (または API で各ハンドラーへの参照を追加する) ファクトリを手動で記述したくありません。
上記に対処するために、実行したいコマンドまたはクエリを受け取る Command / Query HandlerFactory があります。リフレクションを使用して、ハンドラーのタイプを見つけ、ベースの handlerResolver を使用して、ハンドラーの新しいインスタンスを取得できるようにします。これを行うには、リゾルバーに渡すILifetimeScope
ので、1 か所でのみ実行されます。(lifetimescope を参照することは一般的にアンチ パターンであることは承知していますが、何百ものコマンドとクエリで終わる場合、考えられるすべての依存関係を取り、autofac を使用して、恐ろしいファクトリになるだろうと感じました配線するとよりきれいになります)。
すべてがリクエストごとのインスタンスとして残されている場合、これはすべて機能し、すべてのクラスが解決され、コマンドとクエリが実行されます。問題は、API リクエストごとに NHibnernate 構成が再構築され、私のマシンでは約 1.5 秒かかることです。これは、ほぼすべてのリクエストが応答するのに最大 2 秒かかることを意味します。
私がやりたいことは、NHibnerate 構成と sessionFactory をシングルトンとして登録できるようにすることです (機密情報やユーザー データに関連する情報がないため)。また、すべてのハンドラーと他のクラスをリクエストに応じて残し、独立してできるだけ早く破棄できるようにします。
Web API を接続するためのメイン クラス:
public static class AutoFacSetup
{
public static IContainer Create()
{
var builder = new ContainerBuilder();
// this is to insist we use hbm config rather than fluent as there are two implentations of IConfigurationFactory
builder.RegisterType<OurHbmConfigurationFactory>().SingleInstance();
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
// Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();
builder.RegisterAssemblyModules(assemblies);
builder.RegisterSelf();
var container = builder.Build();
return container;
}
public static void RegisterSelf(this ContainerBuilder builder)
{
IContainer container = null;
builder.Register(c => container).AsSelf().SingleInstance();
builder.RegisterBuildCallback(c => container = c);
}
}
モジュール クラスの 1 つの例:
public class AutoFacInstallerModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var assembly = GetType().Assembly;
builder
.RegisterAssemblyTypes(assembly)
.Except<NhibernateDbConnectionFactory>(x => x.SingleInstance())
.Except<MySessionFactory>(x => x.SingleInstance())
.AsImplementedInterfaces()
.InstancePerRequest();
}
}