代码之家  ›  专栏  ›  技术社区  ›  Chris Canal

将IOC容器抽象到一个单独的实例后面-是不是做错了?

  •  10
  • Chris Canal  · 技术社区  · 17 年前

    一般来说,我喜欢让应用程序完全不了解IOC容器。但是我在需要访问它的地方遇到了问题。为了消除疼痛,我使用了一个基本的单子。在你跑上山或者拔出猎枪之前,让我来看看我的解决方案。基本上,IOCSingleton绝对不做任何事情,它只是委托给一个必须传入的内部接口。我发现这样可以减少单身汉的痛苦。

    以下是国际奥委会的包装:

    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>();
        }
    

    到目前为止,我已经成功地使用了几次(也许每隔几次项目,我真的不喜欢使用这个),因为我可以注入任何我想要的东西:城堡、树桩、假货等等。

    这条路滑吗?我是否会遇到潜在的问题?

    4 回复  |  直到 8 年前
        1
  •  4
  •   Julian Birch    17 年前

    我已经看到即使是Ayende也在Rhino公共代码中实现了这种模式,但我建议尽可能不要使用它。在默认情况下,温莎城堡没有此代码是有原因的。结构图是的,但杰里米·米勒已经离开了它。理想情况下,您应该将容器本身与任何全局变量一样视为可疑变量。

    但是,作为替代方案,您可以始终将容器配置为将IDependencyResolver解析为对容器的引用。这听起来可能很疯狂,但它明显更灵活。只要记住经验法则,对象应该调用“new”或执行处理,但不能同时调用两者。对于“call new”,替换为“resolve a reference”。

        2
  •  3
  •   Sam Mackrill    13 年前

    这可不是一门独身课。这是一个包含静态成员的静态类。是的,这似乎是一个很好的方法。

    我认为JPBoodhoo甚至有这个模式的名字。 The Static Gateway pattern .

        3
  •  2
  •   Craig Wilson    17 年前

    只需注意:Microsoft模式和实践已经创建了一个通用的服务定位器( http://www.codeplex.com/CommonServiceLocator )大部分主要的国际奥委会容器将在不久的将来实施。您可以开始使用它而不是IDependencyResolver。

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

        4
  •  1
  •   jgauffin    13 年前

    这完全取决于用法。使用这样的容器称为服务定位器模式。有些情况下,它并不适合,有些情况下,它确实适用。

    如果你搜索“服务定位器模式”,你会看到很多博客文章说这是一个反模式,而不是。模式只是被过度使用了(被滥用)。

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

    服务定位器在基础设施方面非常适合。例如,ASP.NET MVC使用服务定位器来解析每个控制器的所有依赖项。