首页 > 代码库 > MVC.Net:MVC.Net与WebAPI的IOC实现

MVC.Net:MVC.Net与WebAPI的IOC实现

我们通过Ninject(http://www.ninject.org/)项目来帮助我们实现MVC.Net与WebAPI项目的IOC实现。

首先我们来看MVC.Net的IOC实现。

1. 通过NuGet我们安装Ninject.MVC3,它会同时安装Ninject、Ninject.Web.Common和Ninject.Web.Common.WebHost。不用被它的名字干扰,它对MVC.Net 5也是适用的。

2. 安装成功后,在MVC.Net的App_Start目录中会多出一个NinjectWebCommon.cs文件。

 

3. 打开此文件,然后在RegisterServices方法中添加类的绑定,例如:

1 private static void RegisterServices(IKernel kernel)
2 {
3     // DBContext必须要per Http Request per Instance。
4     kernel.Bind<DemoModelContainer>().ToSelf().InRequestScope();
5 
6     kernel.Bind<IPostService>().To<PostService>();
7 
8     kernel.Bind<IPostRepository>().To<PostRepository>();
9 }

4. 这时我们就可以在直接在类中引用接口,而不用是指定该接口是由哪个具体类实现的。例如:

 1 private DemoModelContainer _dbContext;
 2 
 3 private IPostService _postService;
 4 
 5 public PostController(DemoModelContainer dbContext, IPostService postService)
 6 {
 7     _dbContext = dbContext;
 8 
 9     _postService = postService;
10 }

5. 在系统运行后,Ninject会自动将接口对应的类给传入构造函数中。另外还有个有趣的代码就是DemoModelContainer。这个类不是一个接口,是一个EntityFramework的DBContext。在这里我们之所以使用Ninject来管理,是为了实现自动针对每个Request来实例化DBContext,同时又能保证在Request销毁后,对应的DBContext实例也同时销毁。如果不通过Ninject,那么我们就需要给每个Controller实现Dispose方法,然后显式销毁。

========================================

对于WebAPI来说,除了以上步骤,还需要多操作几步:

1. 创建NinjectResolver.cs和NinjectScope.cs两个类文件,代码如下:

NinjectResolver.cs

 1 using Ninject;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Http.Dependencies;
 7 
 8 namespace NinjectWebApi.Models
 9 {
10     public class NinjectResolver : NinjectScope, IDependencyResolver
11     {
12         private IKernel _kernel;
13         public NinjectResolver(IKernel kernel)
14             : base(kernel)
15         {
16             _kernel = kernel;
17         }
18         public IDependencyScope BeginScope()
19         {
20             return new NinjectScope(_kernel.BeginBlock());
21         }
22     }
23 }

NinjectScope.cs

 1 using Ninject.Activation;
 2 using Ninject.Parameters;
 3 using Ninject.Syntax;
 4 using System;
 5 using System.Collections.Generic;
 6 using System.Linq;
 7 using System.Web.Http.Dependencies;
 8 
 9 namespace NinjectWebApi.Models
10 {
11     public class NinjectScope : IDependencyScope
12     {
13         protected IResolutionRoot resolutionRoot;
14 
15         public NinjectScope(IResolutionRoot kernel)
16         {
17             resolutionRoot = kernel;
18         }
19 
20         public object GetService(Type serviceType)
21         {
22             IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
23             return resolutionRoot.Resolve(request).SingleOrDefault();
24         }
25 
26         public IEnumerable<object> GetServices(Type serviceType)
27         {
28             IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
29             return resolutionRoot.Resolve(request).ToList();
30         }
31 
32         public void Dispose()
33         {
34             IDisposable disposable = (IDisposable)resolutionRoot;
35             if (disposable != null) disposable.Dispose();
36             resolutionRoot = null;
37         }
38     }
39 }

2. 修改NinjectWebCommon.cs的CreateKernel方法:

 1 private static IKernel CreateKernel()
 2 {
 3     var kernel = new StandardKernel();
 4     try
 5     {
 6         kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
 7         kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
 8 
 9         RegisterServices(kernel);
10 
11         // WebApi项目必须添加此行
12         System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = 
13             new NinjectWebApi.Models.NinjectResolver(kernel);
14 
15         return kernel;
16     }
17     catch
18     {
19         kernel.Dispose();
20         throw;
21     }
22 }

其它的操作都和MVC.Net一样,这样WebAPI的IOC也实现了。