9

我刚刚开始使用 IoC 容器,如果这是一个愚蠢的问题,我深表歉意。

我在应用程序中有如下代码

internal static class StaticDataHandlerFactory
    {
        public static IStaticDataHandler CreateHandler(StaticDataUpdate staticDataUpdate)
        {
            if (staticDataUpdate.Item is StaticDataUpdateOffice)
            {
                return new OfficeUpdateHandler();
            }

            if (staticDataUpdate.Item is StaticDataUpdateEmployee)
            {
                return new EmployeeUpdateHandler();   
            }

            if (staticDataUpdate.Item == null)
            {
                throw new NotImplementedException(
                    string.Format("No static data provided"));
            }
            else
            {
                throw new NotImplementedException(
                    string.Format("Unimplemented static data type of {0}", staticDataUpdate.Item.GetType().FullName));
            }
        }
    }

它基本上是一个简单的工厂,它返回处理输入数据的正确策略。

IoC 容器会允许我消除这样的代码吗?也就是说:它是否允许我根据输入参数的类型动态选择要加载的具体实现?

还是我在这里偏离了方向?

4

5 回答 5

9

实际上,虽然可以用控制系统反转来替换一些代码,但对我来说并不明显这是一个好主意。依赖注入往往最适合系统配置,而不是对象的动态创建。换句话说,容器本身是一个巨大的全局变量,因此应该出现在您的大部分代码中。

顺便说一句,该代码似乎违反了得墨忒耳法则。看来参数应该是“StaticDataUpdateItem”类型而不是“StaticDataUpdate”类型。观察到这一点,有一个非常强大的论点来将此代码重写为对 StaticDataUpdateItem 的方法调用。

我大量使用了 IoC,但使用抽象工厂模式仍然可以更好地处理动态对象创建。简而言之,如果您不喜欢向项目本身添加方法以生成句柄的想法,那么代码可能最好保持原样。

于 2008-11-13T09:54:17.133 回答
3

你一点也不偏离路线;按照我的理解,你已经很接近了。

我最常用的构建此类事物的方式是将您的 Factory 类转换为您的 IoC 容器,只需允许使用依赖注入指定返回的 UpdateHandlers。因此,您可以将代码转换为简单地说 StaticDataUpdateOffice 返回(新指定的)m_officeUpdateHandler变量包含的任何内容,而不是在代码中指定 StaticDataUpdateOffice 意味着返回 OfficeUpdateHandler 的逻辑;只要您的框架确保您m_officeUpdateHandler在调用工厂之前设置了 的值,您就可以开始了。您可以根据m_officeUpdateHandler需要在运行时将 的值更改为您想要的任何值。

这种依赖注入允许您控制控制反转过程;您可以有一个简单的工厂来返回您的处理程序,并且您可以根据需要抽象控制哪些处理程序返回到不同位置的逻辑。

注意:我对这类事情的体验很大程度上是由我对 Spring 的(非常积极的)体验所驱动的,因此这可能会影响我对您的问题(和答案)的解释。

于 2008-11-11T23:17:36.187 回答
1

简短的回答是肯定的,它允许这样做。这篇博文展示了一种使用 Windsor 在运行时选择实现的巧妙方法。作者 Ayende在此处此处进行了详细说明。

我还没有尝试过,但我希望很快。

于 2008-11-11T22:57:53.793 回答
1

我同意这里的其他答案,是的,你可以这样做。但是,为什么不使用泛型呢?

public static IStaticDataHandler CreateHandler<T>( params object[] args )
{...

其中 args 可以作为 ctor 参数传入(例如,Activator)。

于 2008-11-12T17:26:35.787 回答
-2

我还没有在这里读到任何有意义的词。

IoC 更适合配置?

动态对象创建更好的是什么?泛型?这都是题外话。

1) 与实现“组合胜过专业化/继承”的福音相比,IoC 只不过是节省时间的好方法。

所以使用 IoC 的规则 #1 是你应该真的厌倦了不得不处理遵循“绑定到合同而不是实现”的长构造函数。

换句话说,出于同样的原因(封装......),这是策略模式作为模板模式的替代方案......但是创建所有额外的接口/抽象类型需要更多的工作,而且还有更多的工作要做每次都使用所有 IServiceProvicerThis 和 IResolverThat ...如果您不厌倦必须繁琐地履行代码合同,例如:

IInterestingService 有趣 = ...但是你得到一个实例..

添加大约三行这样的..

然后

IAmazementService 服务 = new AmazementService(有趣,thesecondstrategy,thethird,等等...)

那变老了。所以 IoC 从来都不是问题,因为任何聪明到可以使用可靠设计进行编码的人都会知道得更好。那些问的人都有错误的答案。

因此,如果您确实满足上述条件,那么绝对。IoC 容器有责任做尽可能多的“创造性”工作,让您可以从让它们处理中受益。最常见的对显式 new 的创作抽象是 Mr. Factory。

达蒙

于 2009-10-11T19:26:51.617 回答