我应该尝试隐藏IoC容器(如果是这样,任何提示)?

时间:2011-08-28 20:12:08

标签: c# inversion-of-control ioc-container

我正在构建一个CMS,它有许多扩展点(数据/内容类型,插件,宏,主题),其中一些扩展需要注册服务。到目前为止,扩展仅依赖于'MyProject.Core'库,如果它们不依赖于任何特定的IoC框架,那将是很好的。现在我在想是否应该构建另一个层来隐藏IoC特定的注册。问题是我需要一些高级功能。

E.g。 NHibernate实现'Data / ContentType'服务(Castle Windsor风格)

container.Register(Component.For<IPageRepository>().ImplementedBy<NHPageRepository>());
container.Register(Component.For<ISessionFactory>().Instance(NHibernateHelper.CreateSessionFactory()));
container.Register(Component.For<ISession>().UsingFactoryMethod(c => c.Resolve<ISessionFactory>().OpenSession()).LifeStyle.PerWebRequest);

第三行是“艰难的一行”。我可以创建一个像

这样的界面
interface IMyContainer
{
    Register<TService>(Func<IMyContainer,TService> factoryMethod)
    Register<TService>(Func<IMyContainer,TService> factoryMethod, LifeStyle lifeStyle)
    // ...
}

但“翻译”此注册(我的IoC抽象)

public class NHInstaller :  IInstaller
{
    public void Install(IMyContainer container)
    {
        container.Register<ISession>(c => c.Resolve<ISessionFactory>().OpenSession(), LifeStyle.PerRequest);
    }
}

到此(温莎)

container.Register(Component.For<ISession>().UsingFactoryMethod(c => c.Resolve<ISessionFactory>().OpenSession()).LifeStyle.PerWebRequest);

可能很难。

那么,我应该尝试进行抽象吗?任何有用的资源? 或者我应该选择一个IoC容器并坚持使用它?

我还可以将现有工具(Castle Windsor或Ninject)的源代码作为我库的一部分,但我并不了解这些许可证。我能这样做吗?我可以更改名称空间和类名以适应我的应用程序的结构吗?我将发布源代码,我并不关心许可证是什么。

2 个答案:

答案 0 :(得分:3)

这取决于你所说的“隐藏”。最佳实践是应用程序中只有一个位置(Composition Root)知道IoC容器。坚持Hollywood Principle - 避免让多个类了解IoC容器。换句话说,不要通过容器;如果非根类需要创建其他对象,则将工厂注入其中。

如果您正在编写框架并且希望允许消费者插入他们选择的IoC容器框架,则可以使用Common Service Locator库。这对大多数项目来说可能有点过头了。 (请参阅Mark Seemann's excellent link我改变措辞的原因。)

答案 1 :(得分:1)

简短回答 - 不,抽象是无用的,你会浪费你雇主的钱。请改为使用Installers对注册进行分区。