1

首先,很抱歉,如果我使用的术语无效,试图正确但不确定是否正确,现在对我来说有点困惑。

我正在使用 Windsor 并且无法确定何时以及如何(我认为)使用基于接口的工厂实例化而不总是正常的ctor(IObj obj).

让我举个例子。我有这个构造函数

private ICache _cache;
private ICache _cache2;
public HomeController(ICacheFactory cacheFactory, ICache cache)
{
    this._cache = cacheFactory.Create<ICacheFactory>();
    this._cache2 = cache;
}

我设置代码的方式,_cache_cache2返回 exakt 相同的对象。为什么我应该使用ICacheFactory实例化类的方式?

这就是我配置它的方式

public interface ICacheFactory
{
    ICache Create<T>();
}

public interface ICache
{
    bool Get<T>(string key, out T exists);
}

public bool Get<T>(string key, out T result)
    {
        // my code
    }

public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient());
        container.AddFacility<TypedFactoryFacility>();
        container.Register(Component.For<ICacheFactory>().AsFactory());

        container.Register(Component.For<ICache>().ImplementedBy<CacheFactory>().LifestyleTransient());
    }

我在想 CacheFactory 就像我做的那样

public class CacheFactory : ICache
{
    private static ICache cacheObject;
    public static ICache Current
    {
        get
        {
            if (cacheObject == null)
                cacheObject = new CacheFactory();

            return cacheObject;
        }
    }

    public bool Get<T>(string key, out T result)
    {
        // my code
    }
}

那么,我是否完整地思考了interface-based factories该做什么,如果不是,我为什么要使用ICacheFactory实例化课程的方式?

(我应该清楚,我已经阅读了 Windsor 文档,但没有 100% 得到它。)

感谢您的时间,我希望它不会模糊。

4

1 回答 1

3

当正确应用依赖注入时,您会发现这将大大减少您需要使用的工厂数量。工厂仍然有用并且有时需要,但它们的使用仅限于您:

  1. 明确需要控制服务的生命周期(例如因为您需要在方法结束时处理此类实例)
  2. 当您需要通过推迟创建来破坏对象图时。

在大多数其他情况下,不应使用工厂。特别是在您展示的情况下,工厂在构造函数中被调用。这是没用的,因为:

  1. 您不会延迟对象图的构建,因为从构造函数内部调用工厂与在调用构造函数之前调用工厂具有相同的效果。
  2. 您正在使您的代码库复杂化,因为您HomeController现在依赖于一个额外的 abstraction ICacheFactory,而它只需依赖于一个就可以满足其需求ICache。这也使测试变得复杂。为什么HomeController需要了解这家工厂?

此外,您声明“_cache 和 _cache2 返回完全相同的对象”,因此无需在此处注入两个缓存。所以你的构造函数应该是这样的:

private ICache _cache;
public HomeController(ICache cache)
{
    this._cache = cache;
}

如果您的工厂包含执行选择的复杂行为,您仍然可以在合成根中使用它,但应用程序代码可能没有理由依赖它。

于 2014-10-27T10:47:42.343 回答