我在我的ASP.NET MVC3项目中使用
NinjectMVC3.
我有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依赖项?
解决方法
为了让你指向正确的方向,我建议你看看
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的引用(通过NuGet只是简单的Ninject,而不是通过NuGet的MVC3 dropin),并添加我在ServiceDIModule上面调用的内容,如下所示:
using Ninject.Modules; namespace MyServiceLayer { public class ServiceDIModule : NinjectModule { public override void Load() { //Bind Services Bind<IPracticeService>().To<PracticeService>().InRequestScope(); } } }
并重复相同的数据层注入过程(UnitofWork,DatabaseFactory,IFooRepository等)
namespace MyDataLayer { public class RepositoryDIModule : NinjectModule { public override void Load() { //Bind Repos Bind<IFooRepository>().To<FooRepository>().InRequestScope(); } } }
现在,您可以预先访问所需的所有绑定.所以,你对我的问题实际上归结为思维的转变.如果您可以接受(不情愿或其他方式)洋葱概念,您的方案将干净利落地解决.
您还可以查看Project Silk和CodeCampServer.它们都在某种程度上实现了“洋葱”概念(Silk肯定,我现在正在寻找解决方案,UI web项目包含对包含所有回购)
让我知道你的想法.