10

通常,我喜欢让应用程序完全不了解 IoC 容器。但是,我遇到了需要访问它的问题。为了消除痛苦,我使用了一个基本的 Singleton。在你跑上山或拔出猎枪之前,让我回顾一下我的解决方案。基本上,IoC 单例完全没有做任何事情,它只是委托给一个必须传入的内部接口。我发现这使得使用单例变得不那么痛苦。

下面是 IoC 包装器:

public static class IoC
    {
        private static IDependencyResolver inner;

        public static void InitWith(IDependencyResolver container)
        {
            inner = container;
        }

        /// <exception cref="InvalidOperationException">Container has not been initialized.   Please supply an instance if IWindsorContainer.</exception>
        public static T Resolve<T>()
        {
            if ( inner == null)
                throw new InvalidOperationException("Container has not been initialized.  Please supply an instance if IWindsorContainer.");

            return inner.Resolve<T>();
        }

        public static T[] ResolveAll<T>()
        {
            return inner.ResolveAll<T>();
        }
    }

IDependencyResolver:

public interface IDependencyResolver
    {
        T Resolve<T>();
        T[] ResolveAll<T>();
    }

到目前为止,我使用它的几次都取得了巨大的成功(也许每隔几个项目一次,我真的不想完全使用它),因为我可以注入任何我想要的东西:Castle,一个存根,假货,等等

这是一条湿滑的路吗?我会在未来遇到潜在的问题吗?

4

4 回答 4

4

我已经看到即使 Ayende 在 Rhino Commons 代码中也实现了这种模式,但我建议尽可能不要使用它。温莎城堡默认没有此代码是有原因的。StructureMap 确实如此,但 Jeremy Miller 一直在远离它。理想情况下,您应该像对待任何全局变量一样怀疑容器本身。

但是,作为替代方案,您始终可以将容器配置为将 IDependencyResolver 解析为对容器的引用。这可能听起来很疯狂,但它明显更加灵活。只要记住一个对象应该调用“新”或执行处理的经验法则,但不能两者兼而有之。对于“调用新”替换为“解决参考”。

于 2008-11-13T10:01:04.000 回答
3

那不是真正的单例类。那是一个带有静态成员的静态类。是的,这似乎是一个好方法。

我认为 JP Boodhoo 甚至为这种模式起了一个名字。静态网关模式

于 2008-11-10T10:34:08.350 回答
2

请注意:Microsoft Patterns and Practices 创建了一个通用服务定位器 ( http://www.codeplex.com/CommonServiceLocator ),大多数主要的 IoC 容器将在不久的将来实施该定位器。您可以开始使用它来代替您的 IDependencyResolver。

顺便说一句:这是解决您的问题的常用方法,并且效果很好。

于 2008-11-11T00:25:14.740 回答
1

这一切都取决于使用情况。像这样使用容器称为服务定位器模式。在某些情况下它不适合,而在某些情况下它确实适用。

如果你用谷歌搜索“服务定位器模式”,你会看到很多博客文章说它是一种反模式,但事实并非如此。该模式只是被过度使用(/滥用)。

对于典型的业务线应用程序,您不应该使用 SL,因为您隐藏了依赖项。您还遇到了另一个问题:如果您使用根容器(而不是其中一个生命周期),则无法管理状态/生命周期。

服务定位器非常适合基础架构。例如,ASP.NET MVC 使用服务定位器来解决每个控制器的所有依赖关系。

于 2013-06-28T09:49:42.333 回答