如何配置Simple Injector以在上下文事务中实现命令处理程序模式

问题描述

我正在尝试在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<,>实现周围。

有关注册通用类型和装饰器的更多信息,请阅读我们的优质文档:

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...