尝试在WebApi中使用Ninject进行依赖注入
1 public class AdminController : ApiController 2 { 3 [Inject] 4 public IAdminService AdminService { get; set; } 5 6 // GET api/admin 7 public IEnumerable<Admin> Get() 8 { 9 return AdminService.Admins(); 10 //return new string[] { "value1", "value2" }; 11 } 12 13 }
结果运行出错,提示NullReferenceException
在网上有查询到一篇博文 http://wildermuth.com/2012/02/26/WebAPI_and_Ninject
先用NuGet安装CommonServiceLocator.NinjectAdapter
修改App_Start下NinjectWebCommon.cs文件private static IKernel CreateKernel(){...}代码段
1 using NinjectAdapter; 2 3 public static class NinjectMVC3 4 { 5 static readonly Bootstrapper bootstrapper 6 = new Bootstrapper(); 7 8 public static void Start() 9 { 10 DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule)); 11 DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule)); 12 13 bootstrapper.Initialize(CreateKernel); 14 15 } 16 17 ... 18 19 static IKernel CreateKernel() 20 { 21 var kernel = new StandardKernel(); 22 23 // Register Dependencies 24 RegisterServices(kernel); 25 26 // Set Web API Resolver 27 GlobalConfiguration.Configuration 28 .ServiceResolver 29 .SetResolver(new NinjectServiceLocator(kernel)); 30 31 return kernel; 32 } 33 ... 34 }
结果:GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectServiceLocator(kernel));
在引用System.Web.Http空间名报错,没找到ServiceResolver,只有DependencyResolver。
解决方法:
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
1 private static IKernel CreateKernel() 2 { 3 var kernel = new StandardKernel(); 4 kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); 5 kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 6 7 RegisterServices(kernel); 8 9 // Set Web API Resolver 10 GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); 11 12 return kernel; 13 }
关于NinjectDependencyResolver这个类代码如下
1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics.Contracts; 4 using System.Web.Http.Dependencies; 5 using Ninject; 6 using Ninject.Syntax; 7 8 namespace WebApiNinject.App_Start 9 { 10 public class NinjectDependencyScope : IDependencyScope 11 { 12 private IResolutionRoot resolver; 13 14 internal NinjectDependencyScope(IResolutionRoot resolver) 15 { 16 Contract.Assert(resolver != null); 17 18 this.resolver = resolver; 19 } 20 21 public void Dispose() 22 { 23 IDisposable disposable = resolver as IDisposable; 24 if (disposable != null) 25 disposable.Dispose(); 26 27 resolver = null; 28 } 29 30 public object GetService(Type serviceType) 31 { 32 if (resolver == null) 33 throw new ObjectDisposedException("this", "This scope has already been disposed"); 34 35 return resolver.TryGet(serviceType); 36 } 37 38 public IEnumerable<object> GetServices(Type serviceType) 39 { 40 if (resolver == null) 41 throw new ObjectDisposedException("this", "This scope has already been disposed"); 42 43 return resolver.GetAll(serviceType); 44 } 45 } 46 47 public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver 48 { 49 private IKernel kernel; 50 51 public NinjectDependencyResolver(IKernel kernel) 52 : base(kernel) 53 { 54 this.kernel = kernel; 55 } 56 57 public IDependencyScope BeginScope() 58 { 59 return new NinjectDependencyScope(kernel.BeginBlock()); 60 } 61 } 62 }
好了,现在可以在ApiController中使用Ninject了。