【问题标题】:Doesn't an Abstract Factory class break the life cycle management of an IoC Container抽象工厂类不会破坏 IoC 容器的生命周期管理吗
【发布时间】:2014-08-07 15:53:08
【问题描述】:
public class MyClassFactory : IMyClassFactory
{ 
    private readonly IMySingleton _mySingleton;
    private readonly IMyNonSingleton _myNonSingleton;

    public MyClassFactory(
        IMySingleton mySingleton, 
        IMyNonSingleton myNonSingleton
        )
    {
        _mySingleton = mySingleton;
        _myNonSingleton = myNonSingleton;
    }

    public IMyResult CreateMyResult(int resultId)
    {
        // right here - have i not arbitrarily extended the lifespan
        //              of _myNonSingleton?  
        //
        return new MyResult(_mySingleton, _myNonSingleton, resultId);
    }
} 

通过此设置,每个新的 MyResult 都将获得相同的 IMyNonSingleton 实例。解决这个问题的唯一方法不是每次创建 MyResult 时都在容器上再次调用 Resolve 吗?

同样,如果我这样做,那不是开始看起来像服务定位器模式吗?至少,我会违反诸如“不要调用容器,它会调用你”和“你只调用 Resolve 一次”这样的规则,对吗?

编辑:这里的想法是 IMySingleton 已在我的容器中注册为单例,而其他类则没有。

【问题讨论】:

  • 我不一定会称之为singletons,而是类似上下文实例。他们没有什么“单身”。
  • @TyCobb - 抱歉,从外观上看,我可以看出我在这里没有画出非常清晰的画面。内涵是IMySingleton已经在我的容器中注册为单例,其他类没有。

标签: c# dependency-injection inversion-of-control containers


【解决方案1】:

您有可能无意中延长对象的生命周期,但它适用于一个对象的生命周期与另一个对象的生命周期不匹配的所有情况。

可能不是问题的情况:

  • 您可能会在每次需要时向工厂询问容器,或者工厂的生命周期与工厂使用的对象的最短生命周期相匹配。
  • 您实际上需要对象具有更长的生命周期(或与工厂匹配)
  • 生命周期较短的对象无关

可能出现问题的情况:

  • 您的工厂具有更长的生命周期(即应用程序),但必须每次或以 IOC 容器管理的其他频率创建对象。

解决方法:

  • 将工厂与容器集成(即将容器传递给工厂并使用其解析方法构造内部对象)
  • 将“创建者”方法而不是实例传递给构造函数,以避免直接依赖容器。
  • 完全放弃工厂并将其直接集成到容器初始化中。

即Microsoft Unity 容器同时注册类型和Func<T>,因此您的工厂可以立即依赖于创建者函数,例如:

 public MyClassFactory(
    Func<IMySingleton> mySingleton, 
    Func<IMyNonSingleton> myNonSingleton
    )...

【讨论】:

  • 感谢您的回复。我目前的解决方法是您的第一个建议。似乎,如果你总是向容器索要你的东西,你永远不会在自己的脚下开枪。对我来说,许多解决问题的呼吁开始“感觉”错了。
  • +1。我要补充一点:努力设计您的组件,以便无论它们在容器中的范围如何,它们都能正常运行。大多数被建模为纯服务的组件可以限定为单例或瞬态,并且工作方式相同。
【解决方案2】:

1) 我认为您可以将 IMyClassFactory 的接口更改为

public interface IMyClassFactory
{
    IMyResult CreateMyResult(int resultId, IMyNonSingleton myNonSinglrton);
}

2) 或者你需要一个 IMyNonSingletonFactory 来重写这样的代码

public class MyClassFactory : IMyClassFactory
{ 
    private readonly IMySingleton _mySingleton;
    private readonly IMyNonSingletonFactory _myNonSingletonFactory;

    public MyClassFactory(
        IMySingleton mySingleton, 
        IMyNonSingletonFactory myNonSingletonFactory
    )
    {
        _mySingleton = mySingleton;
        _myNonSingletonFactory = myNonSingletonFactory;
    }

    public IMyResult CreateMyResult(int resultId)
    {
        //you need your definition of INonSingletonFactory
        return new MyResult(_mySingleton, _myNonSingletonFactory.Create(), resultId);
    }
} 

【讨论】:

  • 感谢您的回复。我明白你的意思了。我认为我的问题的另一部分是我的代码最终看起来像工厂中心。每次做一个无法解析的类,就得为它再做一个类工厂。这种情况经常发生在我们的 UI 方面,所有这些都开始让人觉得相当乏味和分散注意力。我想,我们一直这样做是为了获得通常的 IoC/DI 好处,但它仍然会让人分心。
猜你喜欢
  • 2012-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 2016-04-12
  • 2013-04-25
  • 2010-12-31
相关资源
最近更新 更多