Ninject binding with generic repository MVC returns error on Parameterless Constructor

强颜欢笑 提交于 2019-12-04 05:19:45

问题


I'm trying to use a fairly simple generic repository for a number of administration lists in an application. Functionality for the admin users is just CRUD to keep the lists up to date for use elsewhere as lookups.

I keep getting an error of the form:

An error occurred when trying to create a controller of type 'WhatWorks.Controllers.AchievementController'. Make sure that the controller has a parameterless public constructor.

I've read an awful lot of posts on SO and blogs found through Google but I can't find an answer (at least nothing that makes sense to me as an answer which may be another problem...)

My code is as follows:

Controller

public class AchievementController : BootstrapBaseController
{
    private readonly IAdminRepository<tAchievement> _repo;

    public AchievementController(IAdminRepository<tAchievement> _repo)
    {
        this._repo = _repo;
    }

ViewModel

public partial class AchievementListViewModel
{
    public int Id { get; set; }
    public string achievement { get; set; }
}

Interface

public interface IAdminRepository<TEntity> : IDisposable 
                    where TEntity : class                            
{
    IEnumerable<TEntity> Get();
    TEntity GetByID(int id);
    void Insert(TEntity entity);
    void Delete(TEntity entity);
    void Update(TEntity entity);
    void Save();
}

Repository

public class AdminRepository<T> : IAdminRepository<T>
                        where T : class
    {
        private WhatWorksEntities objContext;

        public AdminRepository()
        {
            objContext = new WhatWorksEntities();
        }

        public IEnumerable<T> Get()
        {
            return objContext.Set<T>().ToList();
        }

        etc.

Binding

kernel.Bind(typeof(IAdminRepository<>)).To(typeof(AdminRepository<>));

I've also tried binding with an additional line to no effect:

kernel.Bind<IAdminRepository<tAchievement>>().To<AdminRepository<tAchievement>>();

I'm assuming I'm missing something simple.

I have Ninject, Ninject.Web.MVC and Ninject.Web.Common in my references - all taken from NuGet.

Stack Trace is as follows:

[MissingMethodException: No parameterless constructor defined for this object.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
   System.Activator.CreateInstance(Type type) +6
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +55

[InvalidOperationException: An error occurred when trying to create a controller of type 'WhatWorks.Controllers.AchievementController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +179
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +197
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +49
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

_____________EDIT with partial answer_____________

Having recreated a project from scratch and hit the same error I noticed that the versions of a few of the additional packages I was using had changed. I'm using "Twitter Bootstrap for MVC" by Eric Hexter as my main display and this is pulling in a later version of Twitter Bootstrap than I've used previously. I'm not sure if this is causing the problem but the layout of the folders in an older working project are different from the new one.

This answer has given me a decent pointer after the comments by Trevor Pilley: Ninject + MVC3 is not injecting into controller

In my older working project the following was in the Web.config file but is not in the new project. If I add it, the code works but there is still a problem with the Twitter Bootstrap layout - probably from the new .css files - I'll leave the question open for in case anyone can improve on this as an answer.

(Entity Framework closing tag left in to show location in Web.config)

  </entityFramework>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

_________EDIT global.asax______________________

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BootstrapSupport.BootstrapBundleConfig.RegisterBundles(System.Web.Optimization.BundleTable.Bundles);
        WhatWorksRouteConfig.RegisterRoutes(RouteTable.Routes);
        AutoMapperConfiguration.Configure();
    }
}

回答1:


You need to tell the MVC runtime to use Ninject to resolve your controllers, the easiest way to do this is install the MVC extension for Ninject



来源:https://stackoverflow.com/questions/18723935/ninject-binding-with-generic-repository-mvc-returns-error-on-parameterless-const

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!