Ninject网页API"确保控制器具有一个无参数的公共构造" [英] Ninject Web Api "Make sure that the controller has a parameterless public constructor."

查看:287
本文介绍了Ninject网页API"确保控制器具有一个无参数的公共构造"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用ninject近2年,但现在使用它时,我的ASP.NET MVC /项目的WebAPI我得到这个消息,并与各种建议计算器以前的线程并没有解决我的问题。
我有后续的NuGet包:
Ninject MVC3
Ninject集成的WebAPI 2



我试过求解问题不再是那个我想也是一样,会很感激的任何帮助,而且我能得到的建议!
(编号很乐意把在Github上的解决方案,如果有人想仔细看看)



下面是我使用的类:

 公共类CmsContext:的DbContext 
{

公共CmsContext()
:基地(CMS_POC )
{}

公共DbSet<活性GT;活动得到{;组; }
公共DbSet< CMS.Entities.System>系统{搞定;组; }

保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
{
modelBuilder.Conventions.Remove< PluralizingTableNameConvention>();

}
}

公共接口IRepository< T>其中T:IEntityBase
{
IEnumerable的< T> GETALL {搞定; }
无效添加(T实体);
无效删除(T实体);
无效更新(T实体); $ B $(B T)GetById(INT ID);
}

公共类SystemRepository:IRepository< CMS.Entities.System>
{
私人CmsContext _systemContext;

公共SystemRepository(CmsContext systemContext)
{
_systemContext = systemContext;
}

公开的IEnumerable< Entities.System> GETALL
{
得到
{
返回_systemContext.Systems;
}
}

公共无效添加(Entities.System实体)
{
_systemContext.Systems.Add(实体);
_systemContext.SaveChanges();
}

公共无效删除(Entities.System实体)
{
_systemContext.Systems.Remove(实体);
_systemContext.SaveChanges();
}

公共无效更新(Entities.System实体)
{
VAR系统= _systemContext.Systems.SingleOrDefault(S = GT; s.System_Id ==实体.System_Id);

系统=实体;
_systemContext.SaveChanges();
}

公共Entities.System GetById(INT标识)
{
返回_systemContext.Systems.SingleOrDefault(S = GT; s.System_Id == ID);



}

 公共类ActivityRepository:IRepository<活性GT; 
{
私人CmsContext _activityContext;

公共ActivityRepository(CmsContext activityContext)
{
_activityContext = activityContext;
}


公开的IEnumerable<活性GT; GETALL
{
得到
{
返回_activityContext.Activities;
}
}

公共无效添加(活动实体)
{

_activityContext.Activities.Add(实体);
_activityContext.SaveChanges();
}

公共无效删除(活动实体)
{
_activityContext.Activities.Remove(实体);
_activityContext.SaveChanges();
}

公共无效更新(活动实体)
{
VAR活性= _activityContext.Activities.SingleOrDefault(A => a.Activity_Id == entity.Activity_Id );

活性=实体;
_activityContext.SaveChanges();

}

公共活动GetById(INT标识)
{
返回_activityContext.Activities.SingleOrDefault(A => a.Activity_Id ==标识);
}


}

公共接口IActivityService
{
IReadOnlyList<活性GT; GetActivities();
活性GetSingleActivity(中间体ID);
活性CreateActivity(字符串activityName,日期时间的startDate,日期结束日期,INT的systenId);
活性UpdateActivity(INT activityId,串activityName,日期时间的startDate,日期结束日期);
无效DeleteActivity(INT activityId);
}

公共接口ISystemService
{
IReadOnlyList< CMS.Entities.System> GetSystems();
CMS.Entities.System GetSingleSystem(中间体ID);
CMS.Entities.System CreateSystem(字符串SYSTEMNAME);
CMS.Entities.System UpdateSystem(INT的systenId,串SYSTEMNAME);
无效DeleteSystem(INT的systenId);
}

公共类ActivityService:IActivityService
{
私人IRepository<活性GT; _activityRepository;
私人IRepository< Entities.System> _systemRepository;

公共ActivityService(IRepository<活性GT; activityRepository,IRepository< Entities.System> systemRepository)
{
_activityRepository = activityRepository;
_systemRepository = systemRepository;
}
}

这是服务类的只有很短的一部分,但我想表明我如何使用DI的服务



终于有配置ninject:

 公共静态类NinjectWebCommon 
{
私人静态只读引导程序引导程序=新的引导程序();

///<总结> ///启动应用
LT
///&; /总结>
公共静态无效的开始()
{
DynamicModuleUtility.RegisterModule(typeof运算(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof运算(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}

///<总结>
///停止应用程序。
///< /总结>
公共静态无效停止()
{
bootstrapper.ShutDown();
}

///<总结>
///创建将管理应用程序的内核。
///< /总结>
///<返回>将创建的内核< /回报>
私有静态的iKernel CreateKernel()
{
变种内核=新StandardKernel();

{
kernel.Bind< Func键<的iKernel>>()ToMethod(CTX =>()=>新建引导程序()内核。);
kernel.Bind&所述; IHttpModule的方式>()到< HttpApplicationInitializationHttpModule>();

RegisterServices(内核);
返回内核;
}

{
kernel.Dispose();
抛出;
}
}

///<总结>
///装入模块或在这里注册您服务!
///< /总结>
///< PARAM NAME =内核>在内核与LT; /参数>
私有静态无效RegisterServices(内核的iKernel)
{
kernel.Bind< IActivityService方式>()为<&ActivityService GT;();
kernel.Bind&所述; ISystemService方式>()到< SystemService>();
kernel.Bind&所述; IRepository&下;活动>方式>()到< ActivityRepository>();
kernel.Bind&所述; IRepository&下; CMS.Entities.System>方式>()到< SystemRepository>();
}
}



编辑*
忘记了我的控制器

 公共类ActivitiesController:ApiController 

{
私人IActivityService _activityService;

公共ActivitiesController(IActivityService activityService)
{
_activityService = activityService;
}
}


解决方案

所以,我从来没有真正使用ninject,但我花了很多时间与在的WebAPI structuremap工作(并且甚至通过的写的WebAPI如何创造控制器),我敢肯定,我知道怎么回事。



它看起来就像你从未登记的WebAPI内核。的WebAPI通过IControllerActivator创建控制器(它可以更换,但可能不希望,因为它做了很多的缓存和东西你),接着调用一个DependencyResolver创建控制器。如果你还没有注册自己的解析器将只使用Activator.CreateInstance(),它抛出,你所看到的错误。



您需要的将是使用从的IDependencyResolver库(如这个),或实现自己的IDependencyResolver和IDependencyScope(一StructureMap的例子可以发现 )。一旦你有一个实现你可以使用Web API这个样子注册:

  GlobalConfiguration.Configuration.DependencyResolver = myResolverImpl; 

如果您有关于这个或任何问题,不能正常工作,请问,这是一个领域,我想确保我明白的事情做好,所以我很想去填补我所知任何漏洞。


I've been using ninject for almost 2 years but now when using it my ASP.NET MVC/WebAPI project i get this message and the previous threads on stackoverflow with various suggestions hasn't solved my problem. I have the follow nuget packages: Ninject MVC3 Ninject Integration for WebApi 2.

I've tried solving the problem for longer that I'd like too and would really appreciate any help and suggestions that i could get! (Id gladly put the solution on Github if someone want to take a closer look)

Here are the classes that I use:

public class CmsContext : DbContext
{

    public CmsContext()
        : base("CMS_POC")
    { }

    public DbSet<Activity> Activities { get; set; }
    public DbSet<CMS.Entities.System> Systems { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

    }
}

public interface IRepository<T> where T : IEntityBase
{
    IEnumerable<T> GetAll { get; }
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    T GetById(int Id);
}

public class SystemRepository : IRepository<CMS.Entities.System>
{
    private CmsContext _systemContext;

    public SystemRepository(CmsContext systemContext)
    {
        _systemContext = systemContext;
    }

    public IEnumerable<Entities.System> GetAll
    {
        get
        {
            return _systemContext.Systems;
        }
    }

    public void Add(Entities.System entity)
    {
        _systemContext.Systems.Add(entity);
        _systemContext.SaveChanges();
    }

    public void Delete(Entities.System entity)
    {
        _systemContext.Systems.Remove(entity);
        _systemContext.SaveChanges();
    }

    public void Update(Entities.System entity)
    {
        var system = _systemContext.Systems.SingleOrDefault(s => s.System_Id == entity.System_Id);

        system = entity;
        _systemContext.SaveChanges();
    }

    public Entities.System GetById(int Id)
    {
        return _systemContext.Systems.SingleOrDefault(s => s.System_Id == Id);

}

public class ActivityRepository : IRepository<Activity>
{
    private CmsContext _activityContext;

    public ActivityRepository(CmsContext activityContext)
    {
        _activityContext = activityContext;
    }


    public IEnumerable<Activity> GetAll
    {
        get
        {
            return _activityContext.Activities;
        }
    }

    public void Add(Activity entity)
    {

        _activityContext.Activities.Add(entity);
        _activityContext.SaveChanges();
    }

    public void Delete(Activity entity)
    {
        _activityContext.Activities.Remove(entity);
        _activityContext.SaveChanges();
    }

    public void Update(Activity entity)
    {
        var activity = _activityContext.Activities.SingleOrDefault(a => a.Activity_Id == entity.Activity_Id);

        activity = entity;
        _activityContext.SaveChanges();

    }

    public Activity GetById(int Id)
    {
        return _activityContext.Activities.SingleOrDefault(a => a.Activity_Id == Id);
    }


 }

public interface IActivityService
    {
        IReadOnlyList<Activity> GetActivities();
        Activity GetSingleActivity(int id);
        Activity CreateActivity(string activityName, DateTime startDate, DateTime endDate, int systemId);
        Activity UpdateActivity(int activityId, string activityName, DateTime startDate, DateTime endDate);
        void DeleteActivity(int activityId);
    }

public interface ISystemService
    {
        IReadOnlyList<CMS.Entities.System> GetSystems();
        CMS.Entities.System GetSingleSystem(int id);
        CMS.Entities.System CreateSystem(string systemName);
        CMS.Entities.System UpdateSystem(int systemId, string systemName);
        void DeleteSystem(int systemId);
    }

    public class ActivityService : IActivityService
    {
        private IRepository<Activity> _activityRepository;
        private IRepository<Entities.System> _systemRepository;

        public ActivityService(IRepository<Activity> activityRepository, IRepository<Entities.System> systemRepository)
        {
            _activityRepository = activityRepository;
            _systemRepository = systemRepository;
        }
}

This is just a short part of the service class but I want to show how I'm using DI with the services.

And finally there configuration for ninject:

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();
        try
        {
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(kernel);
            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IActivityService>().To<ActivityService>();
        kernel.Bind<ISystemService>().To<SystemService>();
        kernel.Bind<IRepository<Activity>>().To<ActivityRepository>();
        kernel.Bind<IRepository<CMS.Entities.System>>().To<SystemRepository>();
    }        
}

EDIT* Forgot my controller

public class ActivitiesController : ApiController

{
    private IActivityService _activityService;

    public ActivitiesController(IActivityService activityService)
    {
        _activityService = activityService;
    }
}

解决方案

So I've never really used ninject but I've spent a lot of time working with structuremap in WebApi (and have even gone through the effort of writing about how WebApi creates controllers) and I'm pretty sure I know whats going on.

It looks like you've never registered your Kernel with WebApi. WebApi creates controllers via a IControllerActivator (which you can replace, but probably don't want to since it does a lot of caching and stuff for you) which in turn calls a DependencyResolver to create your controller. If you haven't registered your own resolver it will just use Activator.CreateInstance() which throws the error you're seeing.

You'll need to either use an IDependencyResolver from a library (such as this one) or implement your own IDependencyResolver and IDependencyScope (a StructureMap example can be found here). Once you have an implementation you can register it with web API like this:

GlobalConfiguration.Configuration.DependencyResolver = myResolverImpl;

If you have any questions about this or this doesn't work please ask, this is an area where I'm trying to make sure I understand things well so I'd love to fill any holes in my knowledge.

这篇关于Ninject网页API&QUOT;确保控制器具有一个无参数的公共构造&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆