【问题标题】:Understanding the difference between using interface-based factories and normal IoC interfaces instansiation了解使用基于接口的工厂和普通 IoC 接口实例化之间的区别
【发布时间】:2014-10-26 22:16:36
【问题描述】:

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

我正在使用 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% 理解。)

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

【问题讨论】:

    标签: .net inversion-of-control castle-windsor factory-pattern windsor-facilities


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

    • 我需要听到的是“在大多数其他情况下,不应该使用工厂。”,我希望这意味着我会知道什么时候需要使用工厂,而不是强迫我使用它们因为这是可能的;)
    猜你喜欢
    • 2016-05-06
    • 2015-07-24
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    相关资源
    最近更新 更多