こんにちは、私は IoC コンテナーを使用しており、コンストラクター内でサービスを初期化したいと考えています (その一部には、データベースと通信する「重い作業」が含まれます)。
この特定のサービスは、挿入されたサービスによって検出された情報を格納します。IPluginToServiceProviderBridge
この情報は、UnitOfWork
.
すべてがブートストラップされると、コマンドを含むコントローラーとハンドラーを含むサービスが、他のすべての対話に使用されます。すべてのコマンドはライフタイム スコープ内にラップされるため、保存と破棄はUnitOfWork
サービスではなくハンドラーによって行われます (これはクリーンなコードに最適です)。
Initializer
すべてがコンストラクターで行われるため、保存とトランザクションの懸念事項を同じように整理して分離することは、サービス内には適用されません。
public PluginManagerService(
IPluginToServiceProviderBridge serviceProvider,
IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
this.serviceProvider = serviceProvider;
lock (threadLock)
{
if (initialised == false)
{
LinkPluginsWithDatabase();
initialised = true;
}
// I don't like this next line, but
// not sure what else to do
this.UnitOfWork.Save();
}
}
protected void LinkPluginsWithDatabase()
{
var plugins =
this.serviceProvider.GetAllPlugins();
foreach (var plugin in plugins)
{
var db = new PluginRecord
{
interfaceType = plugin.InterfaceType;
var id = plugin.Id;
var version = plugin.Version;
}
// store in db via unit of work repository
this.unitOfWork.PluginsRepository.Add(db);
}
}
いくつかのポイント:
スコープの有効期間の処理が複雑になるため、理想的にはファクトリの使用を避けたいと考えています。
サービスに別のメソッドを用意することは本当に避けたいと思ってInit()
いますが、コマンド/ハンドラーを介したトランザクションと保存が可能になりますが、多くのチェック コードが必要になり、一時的な問題も発生すると思います。
上記を考えると、コンストラクター内で呼び出すことは受け入れられますUnitOfWork.Save()
か?それとも、よりクリーンなコードとより良い分離のためにリファクタリングできますか?