Ninject - 静态类中的内核在类库项目中

3
我有一个和Ninject - Kernel in static class?相同的问题,但我没有使用WCF,只是一个类库。
在任何时候实例化内核还是拥有一个静态内核更好?我的UI(现在在MVC应用程序中)消费服务,所以它会调用静态内核吗?什么是最好的方法?
3个回答

6
使用IoC时,首选的方法是尽可能少地使用内核。应在初始化时将其用于连接所有内容,之后迅速而悄无声息地淡出背景。因此,应用了“好莱坞原则”:“不要调用IoC容器,让它调用你!” 包含内核的静态类是所谓的服务定位器反模式,请参见这里
简而言之:您将使用构造函数注入来注入依赖项,而不是每次创建内核或引用静态类。

你需要使用构造函数注入来注入依赖项,而不是每次创建内核或引用静态类。请问您能解释一下吗?如果内核本身未实例化,内核如何拦截构造函数? - riadh gomri
在初始化时,您可以使用内核来创建具有依赖关系的任何服务,并且可能会使用内核支持的工厂来生成特定类型的实例。之后,您只需要访问服务或工厂,看起来似乎没有涉及到IoC容器。 - Alexander R

0

MVC扩展的Ninject,那么为什么不在MVC UI中使用它呢?

而WCF服务可以有自己的组合根。当然,您可以在两者中重用一个NinjectModule实现。因此,Kernel没有必要是静态的,在每个组合根中重用NinjectModule实现即可。

例如,您的应用程序配置:

public class ApplicationModule : NinjectModule
{
    public override void Load()
    {
        Bind<IAbstraction>().To<Implemtation>();
        //  and other general bindings
    }
}

Ninject与MVC

public class YourWebApplication : NinjectHttpApplication
{
  public override IKernel CreateKernel()
  {
     var kernel = new StandardKernel(new ApplicationModule ());

     // add some UI specific bindings, for example authorization
     kernel.Bind<IAuthProvider>().To<AuthProvider>();

     // binding between service contract and implementation/client
     kernel.Bind<IServiceContract>().To<WcfServiceClient>();

     return kernel;
  }
}

还有Ninject与WCF

public class Global : NinjectWcfApplication
{
    protected override IKernel CreateKernel()
    {
        var kernel = new StandardKernel(new ApplicationModule ());

        // add some service specific bindings, for example authorization
        // service has also some other small services that i call providers 
        // so ex Service 1 : has Iprovider1 Iprovider2 Iprovider3 
        kernel.Bind<IProvider1>().To<Provider1>();
        kernel.Bind<IProvider2>().To<Provider2>();
        kernel.Bind<IProvider3>().To<Provider3>();

        return kernel;
    }
}

抱歉,但我真的不明白。 是的,我在UI中使用Ninject和MVC来选择适当的服务实现。 事实上,在我的服务中,我还有一些其他的小服务,我称之为提供者。 所以例如:Service1:有Iprovider1、Iprovider2、Iprovider3等。 因此,我希望在服务中注入正确的提供者(静态的、从数据库中获取的、用于测试的)。 希望您能理解我。 - riadh gomri
有两个问题:1. MVC 和 Service1 是否在同一个 AppDomain 中?2. 它们是否来自同一源代码树?如果至少第一个是“是”,那么一个 Kernel 就可以注入所有内容。如果第一个是“否”,但它们来自同一源代码树(第二个是“是”),则配置可以被重用。无论如何,创建一个静态的 Kernel 将引入额外的依赖项,但不会解决它。 - Akim
没有MVC和Service在同一个库中,MVC与Contracts库交互(该库定义服务层的公共接口)。这就是为什么我希望MVC使用Ninject选择正确的服务,但在一个服务中,我可以注入正确的提供程序。我认为我会将所有内容都设为public,并使用Ninject为服务和提供程序注入依赖项。这样做是否正确? - riadh gomri
好的,这里是更新后的示例。它具有整个项目“ApplicationModule”的常见配置,并且对于UI和服务的自定义_composition roots_具有单独的绑定。您可以使用_Convention over Configuration_和自动发现扩展此示例。 - Akim
谢谢Akim,非常感谢你的帮助,我会尝试理解组合根,并给你反馈。 - riadh gomri
顺便提一下,Mark Seemann有一本关于DI的好书——是学习的好起点。 - Akim

0

Mark Seemann在他的博客http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx中说道:只有应用程序应该有组合根,库和框架不应该有。

这回答了我的问题,我更好地理解了组合根模式。感谢Akim和Alexander R的帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接