Ninject Web Api“确保控制器具有无参数的公共构造函数。”

时间:2015-09-24 12:48:33

标签: c# asp.net-web-api ninject

我已经使用ninject差不多2年但是现在使用它我的ASP.NET MVC / WebAPI项目时我得到了这条消息,而stackoverflow上的先前线程提供了各种建议并没有解决我的问题。 我有以下nuget包: Ninject MVC3 WebApi 2的Ninject集成。

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

以下是我使用的课程:

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

这只是服务类的一小部分,但我想展示我如何在服务中使用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;
    }
}

1 个答案:

答案 0 :(得分:3)

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

您似乎从未使用WebApi注册内核。 WebApi通过IControllerActivator创建控制器(您可以替换它,但可能不想,因为它会为您执行大量缓存和操作),而后者又会调用DependencyResolver来创建控制器。如果您还没有注册自己的解析器,它只会使用Activator.CreateInstance()来抛出您看到的错误。

您需要使用库中的IDependencyResolver(例如this one)或实现您自己的IDependencyResolver和IDependencyScope(可以找到StructureMap示例here)。实现后,您可以将其注册到Web API,如下所示:

GlobalConfiguration.Configuration.DependencyResolver = myResolverImpl;

如果您对此有任何疑问或者这不起作用请问,这是我努力确保理解得很好的一个领域,所以我很乐意填补空缺据我所知。