複数のサービスがあり、それぞれがSimpleInjectorIoCコンテナーを使用してコンストラクターに注入さUnitOfWork
れています。
現在、各インスタンスが個別のオブジェクトであることがわかりUnitOfWork
ます。これは、Entity Frameworkを使用していて、すべての作業単位で同じコンテキスト参照が必要なため、問題があります。
UnitOfWork
解決リクエストごとに同じインスタンスがすべてのサービスに注入されるようにするにはどうすればよいですか?コマンドが完了すると、外部のUnitOfWor
コマンドハンドラデコレータによって保存されます。
これは共通のライブラリであり、MVCフォームとWindowsフォームの両方で使用されることに注意してください。可能であれば、両方のプラットフォーム用の汎用ソリューションがあると便利です。
コードは以下のとおりです。
// snippet of code that registers types
void RegisterTypes()
{
// register general unit of work class for use by majority of service layers
container.Register<IUnitOfWork, UnitOfWork>();
// provide a factory for singleton classes to create their own units of work
// at will
container.RegisterSingle<IUnitOfWorkFactory, UnitOfWorkFactory>();
// register logger
container.RegisterSingle<ILogger, NLogForUnitOfWork>();
// register all generic command handlers
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies());
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));
// register services that will be used by command handlers
container.Register<ISynchronisationService, SynchronisationService>();
container.Register<IPluginManagerService, PluginManagerService>();
}
以下の行の望ましい結果は、構築されたオブジェクトグラフ全体で共有UnitOfWorkインスタンスを持つオブジェクトを作成することです。
var handler = Resolve<ICommandHandler<SyncExternalDataCommand>>();
これが私のサービスです:
public class PluginManagerService : IPluginSettingsService
{
public PluginManagerService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
private readonly unitOfWork;
void IPluginSettingsService.RegisterPlugins()
{
// manipulate the unit of work
}
}
public class SynchronisationService : ISynchronisationService
{
public PluginManagerService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
private readonly unitOfWork;
void ISynchronisationService.SyncData()
{
// manipulate the unit of work
}
}
public class SyncExternalDataCommandHandler
: ICommandHandler<SyncExternalDataCommand>
{
ILogger logger;
ISynchronisationService synchronisationService;
IPluginManagerService pluginManagerService;
public SyncExternalDataCommandHandler(
ISynchronisationService synchronisationService,
IPluginManagerService pluginManagerService,
ILogger logger)
{
this.synchronisationService = synchronisationService;
this.pluginManagerService = pluginManagerService;
this.logger = logger;
}
public void Handle(SyncExternalDataCommand command)
{
// here i will call both services functions, however as of now each
// has a different UnitOfWork reference internally, we need them to
// be common.
this.synchronisationService.SyncData();
this.pluginManagerService.RegisterPlugins();
}
}