我有一个ASP.NET MVC 4应用程序,我想实现工作单元模式.
在我的Web项目中,我有:
IocConfig.cs
using System.Web.Http; using NinjectMVC.Data; using NinjectMVC.Data.Contracts; using Ninject; namespace NinjectMVC { public class IocConfig { public static void RegisterIoc(HttpConfiguration config) { var kernel = new StandardKernel(); // Ninject IoC // These registrations are "per instance request". // See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/ kernel.Bind<RepositoryFactories>().To<RepositoryFactories>() .InSingletonScope(); kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>(); kernel.Bind<INinjectMVCUow>().To<NinjectMVCUow>(); // Tell WebApi how to use our Ninject IoC config.DependencyResolver = new NinjectDependencyResolver(kernel); } } }
Global.asax中
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace NinjectMVC { // Note: For instructions on enabling IIS6 or IIS7 classic mode,// visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); // Tell WebApi to use our custom Ioc (Ninject) IocConfig.RegisterIoc(GlobalConfiguration.Configuration); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); } } }
PersonsController.cs
using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using NinjectMVC.Data.Contracts; using NinjectMVC.Model; namespace NinjectMVC.Controllers { public class PersonsController : ApiControllerBase { public PersonsController(INinjectMVCUow uow) { Uow = uow; } #region OData Future: IQueryable<T> //[Queryable] // public IQueryable<Person> Get() #endregion // GET /api/persons public IEnumerable<Person> Get() { return Uow.Persons.GetAll() .OrderBy(p => p.FirstName); } // GET /api/persons/5 public Person Get(int id) { var person = Uow.Persons.GetById(id); if (person != null) return person; throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); } // OData: GET /api/persons/?firstname=\'Hans\'' // With OData query Syntax we would not need such methods // /api/persons/getbyfirstname?value=Joe1 [ActionName("getbyfirstname")] public Person GetByFirstName(string value) { var person = Uow.Persons.GetAll() .FirstOrDefault(p => p.FirstName.StartsWith(value)); if (person != null) return person; throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); } // Update an existing person // PUT /api/persons/ public HttpResponseMessage Put(Person person) { Uow.Persons.Update(person); Uow.Commit(); return new HttpResponseMessage(HttpStatusCode.NoContent); } } }
当我尝试冲浪时:http://www.domain.com/Persons/Get我得到:
没有为此对象定义无参数构造函数.
有没有我错过的东西?我将不胜感激任何帮助.
这是项目的zip文件,以便更好地参考:
解决方法
Wep.API使用与MVC框架不同的IDependencyResolver.
当您使用HttpConfiguration.DependencyResolver时,它仅适用于ApiControllers.但你的ApiControllerBase派生自Controller …
所以你的ApiControllerBase应该继承自ApiController.
在ApiBaseController.cs中更改它:
public abstract class ApiControllerBase : ApiController { }
如果要将依赖项注入常规Controller派生类,则需要使用(在IocConfig中):
System.Web.Mvc.DependencyResolver.SetResolver(new NinjectMvcDependencyResolver(container));
请注意,在这种情况下,您无法使用NinjectDependencyResolver,因为它适用于ApiControllers.
所以你需要一个不同的NinjectMvcDependencyResolver,它应该实现System.Web.Mvc.IDependencyResolver.
public class NinjectMvcDependencyResolver: NinjectDependencyScope,System.Web.Mvc.IDependencyResolver { private IKernel kernel; public NinjectDependencyResolver(IKernel kernel) : base(kernel) { this.kernel = kernel; } }