如何在ScopedLifestyle的上下文中在decoratee和decorator之间共享实例

问题描述

我不明白如何使用DI容器在decoratee和decorator之间共享实例。

以下示例说明了我的问题。 context实例在TransactionCommandDecoratorCommand服务之间共享。

var context = UowFactory.GetUnitOfWork();

var command = new TransactionCommandDecorator(
    context,new Command(context));
    
command.Execute(new CommandParams { });

context.dispose();

基本上,我需要有许多与数据库交互并调用存储库的命令。然后,我想通过使用包装命令服务的装饰器来应用事务。

问题是我不知道如何在装饰者和被装饰者之间共享上下文(例如在示例中),因为每次执行命令都需要有一个新的DbContext实例。 / p>

您是否解释了如何在范围流动(ScopedLifestyle.Flowing)的上下文中使用Simple Injector使其工作。

这个装饰器和被装饰者实现的可能例子

命令示例:

public Command(IUnitOfWork uow) => _uow = uow;

public DbResult Execute(CommandParams args)
{
    _uow.Repo1.Add(args.Item);
    _uow.Repo1.Add(args.Item2);
    _uow.Repo1.Remove(args.Item3);
}

事务命令装饰器:

public class TransactionCommandDecorator : ICommand
{
    public TransactionCommandDecorator(IUnitOfWork uow,ICommand command)
    {
        _uow = uow;
        _command = command;
    }

    public DbResult Execute(commandParams args)
    {
        try
        {
            var transaction = _uow.GetContext().Database.GetTransaction();
            var ret = _command.Execute(args);
            
            if (!ret.Success)
            {
                transaction.discard();
                return;
            }
            
            transaction.Commit();
        }
        catch
        {
            transaction.discard();
        }
        finally
        {
            transaction.dispose();
        }
    }
}

解决方法

通过将IUnitOfWork注册为Scope,可以在具有相同Lifestyle.Scoped的类之间共享container.Register<IUnitOfWork>(() => UowFactory.GetUnitOfWork(),Lifestyle.Scoped); container.Register<ICommand,Command>(); container.RegisterDecorator<ICommand,TransactionCommandDecorator>(); ,如以下示例所示:

using (var scope = new Scope(container))
{
    ICommand command = scope.GetInstance<ICommand>();

    command.Execute(new CommandParams { });
}

用法(使用ScopedLifestyle.Flowing):

using (AsyncScopedLifestyle.BeginScope(container))
{
    ICommand command = container.GetInstance<ICommand>();

    command.Execute(new CommandParams { });
}

用法(使用环境范围界定):

Add id:12 name:"Sandik" singer:"Muslum Gurses" year:2009 count:5 price:20

相关问答

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