Ninject 网页 Api "Make sure that the controller has a parameterless public constructor."

Ninject Web Api "Make sure that the controller has a parameterless public constructor."

我已经使用 ninject 将近 2 年了,但现在在我的 ASP.NET MVC/WebAPI 项目中使用它时,我收到了这条消息,并且之前关于 Whosebug 的线程有各种建议'解决了我的问题。 我有以下 nuget 包: Ninject MVC3 Ninject WebApi 2 集成。

我已经尝试解决这个问题的时间比我想要的更长,非常感谢我能得到的任何帮助和建议! (如果有人想仔细看看,我很乐意将解决方案放在 Github 上)

这是我使用的 classes:

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;
        }
}

这只是服务的一小部分 class 但我想展示我是如何将 DI 与服务一起使用的。

最后是 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>();
    }        
}

编辑* 忘记了我的控制器

public class ActivitiesController : ApiController

{
    private IActivityService _activityService;

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

所以我从来没有真正使用过 ninject 但我花了很多时间在 WebApi 中使用结构图(甚至经历了 writing about how WebApi creates controllers 的努力)并且我是我很确定我知道发生了什么。

您似乎从未使用 WebApi 注册过您的内核。 WebApi 通过 IControllerActivator 创建控制器(您可以替换它,但可能不想这样做,因为它为您做了很多缓存和其他事情),然后调用 DependencyResolver 来创建您的控制器。如果您还没有注册自己的解析器,它只会使用 Activator.CreateInstance() 抛出您看到的错误。

您需要使用库中的 IDependencyResolver(例如 this one) or implement your own IDependencyResolver and IDependencyScope (a StructureMap example can be found here)。一旦你有了一个实现,你可以像这样在网络 API 上注册它:

GlobalConfiguration.Configuration.DependencyResolver = myResolverImpl;

如果您对此有任何疑问或这不起作用,请询问,这是一个我试图确保我理解得很好的领域,所以我很乐意填补我知识中的任何漏洞。