我尝试为ms sql db创建通用存储库。早些时候我使用mongo db工作过这样的事情。我可以编译项目。但是当我尝试发送请求时,我看到错误:“尝试创建'EmployeeController'类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。”有人可以帮助我吗?
namespace TestTask.Util
{public class NinjectDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
// repository
kernel.Bind<IEmployeeRepository>().To<EmployeeRepository>();
}
}
控制器
namespace TestTask.Controllers
{
[RoutePrefix("api/v1")]
public class EmployeeController : ApiController
{
private readonly IEmployeeRepository _employeeRepository;
public EmployeeController(IEmployeeRepository employeeRepository) : base()
{
_employeeRepository = employeeRepository;
}
[HttpGet]
[Route("getItems")]
public IHttpActionResult GetItems(int take = 8, int skip = 0)
{
if(take<1|| skip < 0)
{
ModelState.AddModelError("Error", "Invalid take or skip params.");
return BadRequest(ModelState);
}
var result = _employeeRepository.Find(x => x.Id >= 0, x=>x.Id, take, skip);
return Ok(result);
}
[HttpGet]
[Route("pageCount")]
public IHttpActionResult PageCount(int itemsInPage)
{
var TotalCount = _employeeRepository.Count(x => x.Id >= 0);
var result = Math.Ceiling((double)TotalCount / (double)itemsInPage);
return Ok(result);
}
}
}
通用存储库
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Web;
namespace TestTask.Context
{
public abstract class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
private DefaultConnection context = new DefaultConnection();
public virtual List<TEntity> Find(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> order, int take =50, int skip=0) //where TEntity : class
{
return context.Set<TEntity>().Where(predicate).OrderBy(order).Skip(skip).Take(take).ToList();
}
public virtual int Count(Expression<Func<TEntity, bool>> predicate)
{
return context.Set<TEntity>().Where(predicate).Count();
}
}
}
答案 0 :(得分:1)
我不得不这样做一段时间,并记住它不像使用Web API那样直接用于MVC。
我在unit of work example here和github project here中发布了详细信息和演示项目。
以下是使用Ninject配置依赖注入的部分。
UnitOfWorkExample.WebApi /控制器/的 ProductsController.cs 强>
namespace UnitOfWorkExample.WebApi.Controllers
{
[RoutePrefix("products")]
public class ProductsController : ApiController
{
private IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
[Route]
public IHttpActionResult GetProducts()
{
// ensure there are products for the example
if (!_productService.GetAll().Any())
{
_productService.Create(new Product { Name = "Product 1" });
_productService.Create(new Product { Name = "Product 2" });
_productService.Create(new Product { Name = "Product 3" });
}
return Ok(_productService.GetAll());
}
}
}
UnitOfWorkExample.WebApi / App_Start /的 NinjectWebCommon.cs 强>
namespace UnitOfWorkExample.WebApi.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using Ninject.Extensions.Conventions;
using System.Web.Http;
using UnitOfWorkExample.Domain.Helpers;
using UnitOfWorkExample.Data.Helpers;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
// Install our Ninject-based IDependencyResolver into the Web API config
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
// unit of work per request
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
// default binding for everything except unit of work
kernel.Bind(x => x.FromAssembliesMatching("*").SelectAllClasses().Excluding<UnitOfWork>().BindDefaultInterface());
}
}
}
UnitOfWorkExample.WebApi / App_Start /的 NinjectDependencyResolver.cs 强>
namespace UnitOfWorkExample.WebApi.App_Start
{
public class NinjectScope : IDependencyScope
{
protected IResolutionRoot resolutionRoot;
public NinjectScope(IResolutionRoot kernel)
{
resolutionRoot = kernel;
}
public object GetService(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).SingleOrDefault();
}
public IEnumerable<object> GetServices(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).ToList();
}
public void Dispose()
{
IDisposable disposable = (IDisposable)resolutionRoot;
if (disposable != null) disposable.Dispose();
resolutionRoot = null;
}
}
public class NinjectResolver : NinjectScope, IDependencyResolver
{
private IKernel _kernel;
public NinjectResolver(IKernel kernel)
: base(kernel)
{
_kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectScope(_kernel.BeginBlock());
}
}
}
答案 1 :(得分:0)
默认情况下,ASP.NET不会向控制器中注入任何内容。相反,它会查找匹配的控制器并使用new
。所以它需要一个没有参数的默认构造函数的控制器 - 除非你做一些特别的事情来添加DI。
要向控制器添加依赖项注入,您需要注册自定义控制器工厂。工厂应该使用Ninject来实例化控制器,控制器将使用适当的依赖关系自动填充其构造函数参数。这是一个简单的例子(你需要修改它以允许其他控制器类型,以及实现接口的其余部分):
public class CustomControllerFactory : IControllerFactory
{
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
return _kernel.Get<EmployeeController>();
}
}
您可以在启动时使用以下代码进行注册:
protected void Application_Start()
{
IControllerFactory factory = new CustomControllerFactory();
ControllerBuilder.Current.SetControllerFactory(factory);
}
可以找到更多信息here。博客显示您正在看到的错误,然后修复它。