8

我在我的ASP.NET MVC3项目中使用NinjectMVC3如何告诉Ninject绑定到它没有参考的实现

我有3层

  • Foo.Web
  • Foo.Services
  • Foo.Data

Foo.Web引用Foo.Services但不Foo.Data。我的一个服务看起来像这样

public class FooService : IFooService 
{ 
    private readonly IFooRepository _fooRepository; 

    public FooService(IFooRepository fooRepository) 
    { 
     _fooRepository = fooRepository; 
    } 

    // ... 
} 

NinjectMVC3执行在Foo.Web启动

private static void RegisterServices(IKernel kernel) 
{ 
    kernel.Bind<IFooService>().To<FooService>(); 
    kernel.Bind<IFooRepository>().To<FooRepository>(); 
    // Foo.Web doesn't know what FooRepository is 
}   

如何从Foo.Web注入FooServices依赖这种方法引导?

+1

Duplicate of:http://stackoverflow.com/questions/5267525/dal-bll-gui-composition-root-how-to-setup-di-bindings – 2011-06-06 00:40:11

回答

7

为了让你在正确的方向,我建议你看一看的onion architecture.

它的基本前提是,任何代码都可以依赖于层的更多的中央。在您的场景中(对于使用Repository模式的MVC3应用程序来说这是常见的),您的UI应该具有对服务层的引用,并且可以接受对数据层的引用。如果你愿意接受这一点(如果你来自传统的N层设置,这是一个难以忍受的药丸,我知道),那么你的情况就变得简单多了。

随着Ninject你现在要做的事情如下:

在你NinjectMVC3.cs提交您CreateKernel变得

/// <summary> 
    /// Creates the kernel that will manage your application. 
    /// </summary> 
    /// <returns>The created kernel.</returns> 
    private static IKernel CreateKernel() 
    { 
     var modules = new INinjectModule[] 
          { 
           new ServiceDIModule(), 
           new RepositoryDIModule() 
          }; 

     var kernel = new StandardKernel(modules); 

     //RegisterServices(kernel); <-- Only if you have some custom binding 
     //        that are UI specific 
     return kernel; 
    } 

现在,在你的服务层,您添加到Ninject(只是普通Ninject参考通过的NuGet,不通过的NuGet的MVC3脱入),并添加什么我打电话,看起来像这样的ServiceDIModule以上:

using Ninject.Modules; 

namespace MyServiceLayer 
{ 
    public class ServiceDIModule : NinjectModule 
    { 
     public override void Load() 
     { 
      //Bind Services 
      Bind<IPracticeService>().To<PracticeService>().InRequestScope(); 
     } 
    } 
} 

和你重复同样的过程FO R上的数据层注射,你可能有(的UnitOfWork,DatabaseFactory,IFooRepository等)

namespace MyDataLayer 
{ 
    public class RepositoryDIModule : NinjectModule 
    { 
     public override void Load() 
     { 
      //Bind Repos 
      Bind<IFooRepository>().To<FooRepository>().InRequestScope(); 
     } 
    } 
} 

现在,您可以访问所有绑定的,你需要这样的前期。所以,你对我的问题真的归结为思维的转变。如果您可以接受(不情愿地或以其他方式)洋葱概念,则您的情况会干净地解决。

您还可以检出Project SilkCodeCampServer。他们都在一定程度上实现了“洋葱”概念(当然,我正在研究解决方案,UI Web项目包含一个包含所有Repos的Data Proj参考)

让我知道你怎么看。

+0

有趣。我仍然不确定你是否只是想让我开除;但是我会玩这个主意。谢谢。 – MVCDatabaseInitializer 2011-06-06 02:03:37

+0

精彩信息,谢谢@Khepri – 2011-08-11 11:55:15