【问题标题】:ASP.NET MVC 4 Ninject MVC 4 Default constructor not found for type 'App.Controller'ASP.NET MVC 4 Ninject MVC 4 未找到类型“App.Controller”的默认构造函数
【发布时间】:2014-12-19 06:00:28
【问题描述】:

我在 Ubuntu 14.04 LTS 上的 Xamarin Studio / monodevelop-opt 中设置了一个新的 ASP.NET MVC 4 应用程序(在 IDE 中运行时为 Mono 3.10.0 mod-mono-server4 / xsp)。安装的软件包有:

Install-Package Microsoft.AspNet.Mvc -Version 4.0.40804
  • Microsoft.AspNet.MVC
  • Microsoft.AspNet.Razor
  • Microsoft.AspNet.WebPages
  • Microsoft.Web.Infrastructure

我还必须安装优化框架:

Install-Package Microsoft.AspNet.Web.Optimization

我选择从 NuGet 实现 IoC 容器 Ninject 并安装了以下软件包:

Install-Package Ninject.Mvc4
  • 忍者
  • Ninject.MVC4
  • Ninject.Web.Common.WebHost
  • Ninject.Web.Common

因为我安装了 Ninject.Mvc4,它在 App_Start 中为我创建了一个名为 NinjectWebCommon.cs 的好文件

这里是创建内核方法:

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

这里是注册服务方法:

    private static void RegisterServices (IKernel kernel)
    {
        kernel.Bind<IResourceEntryService> ().To<ResourceEntryService> ();

        var modules = new List<INinjectModule> {
            new ConfigModule (),
            new RepositoryModule (),
            new LoggingModule ()
        };

        kernel.Load (modules);
    }

资源入口服务及接口:

public interface IResourceEntryService
{
    IEnumerable<ResourceEntry> GetResourceEntries ();

    IEnumerable<ResourceEntry> GetResourceEntriesByNameAndCulture (string name, string culture);
}

public class ResourceEntryService : IResourceEntryService
{
    IResourceEntryRepository _resourceEntryRepository;

    public ResourceEntryService (IResourceEntryRepository resourceEntryRepository)
    {
        _resourceEntryRepository = resourceEntryRepository;
    }

    #region IResourceEntryService implementation

    public System.Collections.Generic.IEnumerable<ResourceEntry> GetResourceEntries ()
    {
        IEnumerable<ResourceEntry> resourceEntries = _resourceEntryRepository.GetResourceEntries ();
        return resourceEntries;
    }

    public System.Collections.Generic.IEnumerable<ResourceEntry> GetResourceEntriesByNameAndCulture (string name, string culture)
    {
        IEnumerable<ResourceEntry> resourceEntries = _resourceEntryRepository.GetResourceEntriesByNameAndCulture (name, culture);
        return resourceEntries;
    }

    #endregion
}

资源入口控制器将新模型对象传递到视图中:

public class ResourceEntryController : Controller
{
    IResourceEntryService _resourceEntryService;

    public ResourceEntryController (IResourceEntryService resourceEntryService)
    {
        _resourceEntryService = resourceEntryService;
    }

    public ActionResult Index ()
    {
        ResourceEntryViewModel viewModel = new ResourceEntryViewModel ();

        return View (viewModel);
    }
}

这是我的 ~/Views/ResourceEntry/Index.cshtml 文件:

@model App.Web.UI.ViewModels.ResourceEntryViewModel

<h1>Resource Page</h1>

所以现在一切看起来都很好,对吧?错了!当我尝试查看该页面时收到以下错误消息。

System.MissingMethodException
Default constructor not found for type App.Web.UI.Controllers.ResourceEntryController

at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00094] in /usr/src/packages/BUILD/mcs/class/corlib/System/Activator.cs:326 
at System.Activator.CreateInstance (System.Type type) [0x00000] in /usr/src/packages/BUILD/mcs/class/corlib/System/Activator.cs:222 
at System.Web.Mvc.DefaultControllerFactory+DefaultControllerActivator.Create (System.Web.Routing.RequestContext requestContext, System.Type controllerType) [0x00000] in <filename unknown>:0 

Version Information: 3.10.0 (tarball Sat Oct 4 16:28:24 UTC 2014); ASP.NET Version: 4.0.30319.17020
Powered by Mono

任何人都知道如何为在单栈上运行的 MVC 4 应用程序设置 Ninject。

我有一个很好的 google'ing 和 stackoverlow'ing 并不能真正找到一个明确的答案。一切都链接到 Web API,我对 Web API 并不真正感兴趣,因为如果涉及到,我将使用 ServiceStack。

我只想让这个 Web 应用程序正常工作。有人有什么建议吗?

更新:2014 年 12 月 20 日

在 windows 下运行良好,但在 Ubuntu 下运行良好

我创建了一个简单的应用程序,可以在这里找到:

Sample Application

有什么想法吗?

2014 年 12 月 21 日更新

我尝试了另一个 IoC 容器的实现。

同样的事情发生了,我认为这可能是 Mono MVC 4 Thing。仍然不知道为什么。

2014 年 12 月 22 日更新

看起来 App_Start 在启动时没有被调用。

我在CreateKernelRegisterServices 中做了一个Console.WriteLine,但没有打印出来。

我可以通过在 Global.ascx.cs 文件中配置容器来使SimpleInjector 工作。如果它在 App_Start 中初始化并在顶部使用以下行,它将无法工作。

[assembly: WebActivator.PostApplicationStartMethod (typeof(App.Web.UI.App_Start.SimpleInjectorInitializer), "Initialize")]

想知道使用 Mono 的 WebActivator 是否存在问题。

【问题讨论】:

  • 似乎 ninject 内核未正确注册为 IDependencyResolver。 Ninject 不会(永远)抛出带有消息“未找到默认构造函数”的MissingMethodException。另见stackoverflow.com/questions/5018810/…
  • 这是一个单注入框架问题?还是我错过了什么/需要添加其他内容?
  • 对不起,我其实不知道。我会研究 ninject.mvc 如何将IKernel 注册为IDependencyResolver 并调试/检查什么不起作用。我不认为这是一个特定于单声道的问题,但正如我所说的,我不知道。
  • 是的,这很奇怪,我遵循与我发现的“洋葱架构”相同的架构。在 Windows 版本的 Xamarin 上编译和运行的 Demo 项目。
  • 如果该演示项目不使用ninject,那么它是否运行良好并不重要......

标签: c# asp.net-mvc-4 mono ninject ioc-container


【解决方案1】:

查看堆栈跟踪,我可以在底部看到 DefaultControllerFactory,它将在内部实例化控制器实例,如下所示:

return Activator.CreateInstance(YourControllerType);

这个调用会变得脾气暴躁,因为你的控制器没有无参数的构造函数,而且你没有提供参数值列表让它找到合适的构造函数来使用......因此例外。 此外,您不想提供参数列表,这会不灵活并且违背 IoC 的目的,而是希望您的 IoC 内核创建实例。

现在,我没有使用 Ninject 的经验,所以可能有一种更“Ninjecty”的方式来做到这一点(如果你知道那是什么,请添加到这里:) 但你需要创建自己的 DefaultControllerFactory 可以确定类型并使用 Ninject 创建它。 像这样的:

// NOTE: Something like this, not exactly, I've not used Ninject!

public class YourControllerFactory : DefaultControllerFactory
{
    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        var type = GetControllerType(requestContext, controllerName);

        return kernel.Get(type);
    }
}

在 Global.asax 中注册:

ControllerBuilder.Current.SetControllerFactory(new YourControllerFactory());

现在您可以控制实例化过程!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    相关资源
    最近更新 更多