IoC的工厂隔离模式

本文关键字:模式 隔离 工厂 IoC | 更新日期: 2023-09-27 18:20:32

据我所知,只有当目标接口不实现IDisposable时,才需要工厂隔离模式。

  1. 因此,对于下面的代码,这将是不正确的用法,因为IDbConnection确实实现了IDisposable。这是正确的吗?

  2. 假设IDbConnection没有实现IDisposable,那么这种用法是正确的。一旦Lambda表达式完成,就会释放IDbConnection。对的

    public class IsolationConnectionFactory : IConnectionIsolationFactory {
        public void With(Action<IDbConnection> do){
            using (var connecion = CreateConnection()){
                do(connection);
            }
        }
    }
    // IConnectionIsolationFactory injected by IoC in this class
    public IEnumerable<TaskDto> GetAllTasks(){
        // Usage
        connectionFactory.With(connection => {
            connection.Open();
            // get data/while read etc
        })
    }
    

IoC的工厂隔离模式

FactoryIsolationPattern在"Adaptive Code Via C#"中介绍。您的客户端代码与用于解释此模式用法的代码类似。正如作者所解释的,模式的意图是,不要用Dispositing逻辑来覆盖类。相反,构造用于确定对象的寿命范围,并在其中提供处理单元。

因此,它不应该影响您是否实现了IDisposable。这就像你使用的是孤立工厂而不是上下文块。

我只在这段代码中看到问题:

public void With(Action<IDbConnection> do){
    using (var connecion = CreateConnection()){
        do(connection);
    }
}

提供该模式是为了添加非一次性接口的处理逻辑。但是您已经在CreateConnection()上放置了using,这意味着这个工厂方法应该返回一个实现了IDisposable的对象。这违背了这种模式的目的。

因此,对于下面的代码,这将是不正确的用法,因为IDbConnection确实实现了IDisposable。这是正确的吗?

我不会说"用法不正确"。我想说,在这种情况下可能不需要它。

但是,有时您可能希望使用隔离工厂,即使工厂的产品实现了IDisposable。您可能需要确保消费者不会忘记处理产品。或者,除了调用IDisposable.Dispose之外,您可能还有其他一些最终确定/发布代码。

假设IDbConnection没有实现IDisposable,那么这种用法是正确的。一旦Lambda表达式完成,就会释放IDbConnection。对的

是的。

在这种情况下,虽然IDbConnection不实现IDisposable,但CreateConnection的返回类型必须实现IDisposable,因为在代码中使用的是using语法。

工厂隔离(anti-)模式具有滥用抽象工厂代码的气味(除非它创建数据结构)。还要注意德米特定律。更优雅的解决方案是代理模式。