【问题标题】:Ninject Web Api "Make sure that the controller has a parameterless public constructor."Ninject Web Api“确保控制器有一个无参数的公共构造函数。”
【发布时间】:2015-09-24 12:48:33
【问题描述】:

我已经使用 ninject 将近 2 年了,但是现在在使用它时,我的 ASP.NET MVC/WebAPI 项目我收到了这条消息,并且 stackoverflow 上的先前线程以及各种建议并没有解决我的问题。 我有以下 nuget 包: 忍者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;
    }
}

【问题讨论】:

  • 如果在RegisterServices 方法中设置断点,它会被命中吗?
  • 我试过了,是的,它确实成功了。
  • 可能是用于解析控制器的内核不是注册类型的内核,调用RegisterServices后尝试解析你的控制器,如果成功,说明ASP.net没有'解析时不要使用正确的内核。
  • 请始终说明完整的异常类型、消息、堆栈跟踪以及任何内部异常。

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


【解决方案1】:

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

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

您需要使用库中的 IDependencyResolver(例如 this one)或实现您自己的 IDependencyResolver 和 IDependencyScope(可以在 here 找到一个 StructureMap 示例)。一旦你有了一个实现,你可以像这样使用 Web API 注册它:

GlobalConfiguration.Configuration.DependencyResolver = myResolverImpl;

如果您对此有任何疑问或此方法不起作用,请提出,这是我努力确保自己理解的领域,因此我很乐意填补我知识中的任何空白。

【讨论】:

  • 你完全正确。我需要注册自己的依赖解析器。这是在一个类似的问题中提出的,但对我没有影响。我创建了自己的,然后它起作用了。
  • 您好,我正在努力解决类似的问题。即使我在 GlobalConfiguration 中注册了解析器,我仍然得到同样的异常。 public MyController(MyHandler handler) { _handler = handler} 抛出相同的异常,但如果我使用 public MyController() { _handler = Kernel.Get&lt;MyHandler &gt;();} 它工作正常......该项目是 ASP .NET WEB API 2 - Owin 应用程序。我已经经历了 50 多个 SO,博客文章仍然无法弄清楚是什么原因造成的。
猜你喜欢
  • 2016-06-20
  • 1970-01-01
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 2016-04-28
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多