问题描述
我正在尝试在WPF应用程序上应用命令处理程序模式。
我在理解如何配置IoC容器(在我的情况下使用Simple Injector)以具有这种功能方面遇到一些问题。
我想执行一个数据库命令处理程序(在DbContext
上执行一些操作),并且每个命令都必须包装在同一上下文中创建的事务中。
这样的事情(仅是一个例子)
public class BusinessUseCases
{
public void BusinessCase1()
{
BusinessCommandParams1 commandParams = new BusinessCommandParams1();
using (var db = new DbContext(connectionString))
{
IDatabaseCommand<DatabaseResult,BusinessCommandParams1> databaseCreate =
new TransactionDatabaseCommandDecorator(new BusinessCommand(db),db);
databaseCreate.Execute(commandParams);
}
}
....
Other business case
}
public interface IDatabaseCommand<TResult,TParam>
{
TResult Execute(TParam commandParam);
}
public class BusinessCommandParams1
{
//some property
}
public class DatabaseResult
{
//some property
}
public class BusinessCommand : IDatabaseCommand<DatabaseResult,BusinessCommandParams1>
{
private readonly DbContext _context;
public BusinessCommand(IDbContext context)
{
_context = context;
}
public DatabaseResult Execute(BusinessCommandParams1 commandParam)
{
//use context
return new DatabaseResult();
}
}
public class TransactionDatabaseCommandDecorator : IDatabaseCommand<DatabaseResult,BusinessCommandParams1>
{
private readonly IDatabaseCommand<DatabaseResult,BusinessCommandParams1> _command;
private readonly DbContext _context;
public TransactionDatabaseCommandDecorator(IDatabaseCommand<DatabaseResult,BusinessCommandParams1> command,DbContext context)
{
_command = command;
_context = context;
}
public DatabaseResult Execute(BusinessCommandParams1 commandParam)
{
using (var transaction = _context.Database.BeginTransaction())
{
try
{
_command.Execute(commandParam);
transaction.Commit();
}
catch (Exception e)
{
Console.WriteLine(e);
transaction.discard();
throw;
}
}
}
}
所以基本上我需要使用POOR MAN DI来实现类似的东西
public class BusinessUseCases
{
public void BusinessCase1()
{
BusinessCommandParams1 commandParams = new BusinessCommandParams1();
using (var db = new DbContext(connectionString))
{
IDatabaseCommand<DatabaseResult,db);
databaseCreate.Execute(commandParams);
}
}
....
Other business case
}
使用简单的进样器或什至另一个IOC容器。
我需要用包装在单个作用域DbContext中的业务案例逻辑来实现命令处理程序。 为了更好地说明,我需要从容器中获取正确的命令处理程序,该命令处理程序将在定义良好的Dbcontext中执行其逻辑,该逻辑将在执行后被丢弃。
但是我不明白如何通过在ioc容器中注册所有类来实现这一点。 也许我的命令处理程序设计或使用DI出了点问题。
您能给我一些例子还是以正确的方式开车给我?
预先感谢
解决方法
简单注入器允许自动注册通用类型,例如命令处理程序。只需调用Container.Register
,即可完成所有命令处理程序的注册:
container.Register(typeof(IDatabaseCommand<,>),typeof(BusinessCommand).Assembly);
在那之后,您可以一个一个地注册装饰器:
container.RegisterDecorator(
typeof(IDatabaseCommand<,typeof(TransactionDatabaseCommandDecorator));
请注意,这种修饰器是通用类型时效果最好,因为在这种情况下,Simple Injector可以将其包装在任何任意IDatabaseCommand<,>
实现周围。
有关注册通用类型和装饰器的更多信息,请阅读我们的优质文档: