使用存储库获取错误没有为此对象定义无参数构造函数

时间:2013-12-31 02:18:21

标签: c# asp.net-mvc linq repository-pattern

我正在学习如何设置存储库。我想简单而愚蠢只是为了让它发挥作用。好的方面是,你可以轻松调试。

HomeController中:

public IUserRepository UserRepository { get; set; }

public HomeController(IUserRepository userRepo)
{
    UserRepository = userRepo;
}

public ActionResult Index()
{
    var users = UserRepository.GetUsers();
    return View(users);
}

的usermodel:

public class UserModel
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public string PasswordHash { get; set; }
    public string PasswordSalt { get; set; }
}

存储库:

public interface IUserRepository
{
    List<UserModel> GetUsers();
}

public class UserRepository : IUserRepository
{
    private GameAlertDBDataContext db = new GameAlertDBDataContext();

    public List<UserModel> GetUsers()
    {
        var userList = from u in db.Users where u.Id == 1 select u;
        var users = new List<UserModel>();

        if (userList.Any())
        {
            foreach (var user in userList)
            {
                users.Add(new UserModel() { Id = user.Id, UserName = user.Username, PasswordHash = user.PasswordHash, PasswordSalt = user.PasswordSalt});
            }

        }
        return users;
    }
}

当我运行我的应用程序时,我得到错误没有为此对象定义无参数构造函数。

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

[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) +66
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +55

[InvalidOperationException: An error occurred when trying to create a controller of type 'FriendAlert.Controllers.HomeController'. 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) +193
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +49
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +49
   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

我想知道我做错了什么?为什么我的存储库无法正常工作?

3 个答案:

答案 0 :(得分:3)

您必须使用依赖注入。 我使用Ninject IoC容器。您可以安装到您的visual studio 工具 - &gt;库包管理器 - &gt;管理NuGet包

然后添加一个这样的类

 public class NinjectControllerFactory : DefaultControllerFactory
{

    private IKernel ninjectKernel;
    public NinjectControllerFactory()
    {
        ninjectKernel = new StandardKernel();
        AddBindings();
    }
    protected override IController GetControllerInstance(RequestContext
    requestContext, Type controllerType)
    {
        return controllerType == null
        ? null
        : (IController)ninjectKernel.Get(controllerType);
    }
    private void AddBindings()
    {
        ninjectKernel.Bind<IUserRepository>().To<UserRepository>();
    }
}

然后在Global.asax

 protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
    }

它将解决问题

答案 1 :(得分:2)

发生此错误是因为mvc框架无法在HomeController中找到无参数构造函数。为了解决这个问题,你只需添加一个无参数构造函数,这样mvc框架就可以实例化HomeController

public HomeController()
{        
}

编辑以完成我的回答,正如@Eranga建议的那样,您应该考虑使用Dependency Injection框架将您的依赖项注入HomeController。您可以参考this问题,了解有关应使用哪个框架的更多信息

答案 2 :(得分:2)

Asp.NET MVC框架无法实例化您的控制器,因为它没有传递构造函数参数的信息。

这里的下一步是使用依赖注入来构造适当的Repository实例并将其注入以创建控制器实例。

看一下像Autofac这样的DI框架以及如何integrate it with MVC