[英]Ninject + MVC3 is not injecting into controller
我已經使用了NuGet Ninject MVC3擴展,並且根據請求無法將其注入控制器。 它似乎沒有綁定,因為MVC正在尋找無參數的構造函數。 這是堆棧跟蹤:
[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) +98
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67
[InvalidOperationException: An error occurred when trying to create a controller of type 'MyApp.Presentation.Controllers.SearchController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
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) +199
System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
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() +8862676
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
而我正試圖注入的控制器(目前需要一個基類):
public class SearchController : MainBaseController
{
private readonly MyApp.Domain.Tutor.TutorSearch TutorSearch;
protected static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
[Ninject.Inject]
public SearchController(MyApp.Domain.Tutor.TutorSearch tutorSearch)
{
this.TutorSearch = tutorSearch;
}
.... (no other constructors)
}
和我的NinjectWebCommon.cs的相關部分:
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
INinjectModule[] modules = new INinjectModule[]
{
new Domain.DomainModule()
};
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Load(modules);
kernel.Bind<MyApp.Domain.Tutor.TutorSearch>().ToSelf();
// ***************
var t = kernel.Get<MyApp.Presentation.Controllers.SearchController>();
}
最后,這是DomainModule:
public class DomainModule : NinjectModule
{
public override void Load()
{
Bind<Data.Profile.IProfileProvider>().To<Data.Profile.XmlProfileProvider>();
Bind<Data.Subject.ISubjectProvider>().To<Data.Subject.XmlSubjectProvider>();
}
}
正如您在標有星號的行中的NinjectWebCommon.cs中所看到的,我已經嘗試將控制器顯式構建為測試。 這適用於正確注入Xml..Providers,效果非常好。
有沒有我錯過的東西? 我不太了解NuGet MVC3擴展的內容,因此不知道控制器綁定在哪個方面失敗。
任何關於看什么的指針都將非常感謝,謝謝。
經過一段時間的絕望修補,我終於找到了問題所在。 我正在引用MVC4(System.Web.Mvc)DLL並且沒有將舊版3.0.0.0的綁定重定向到4.0.0.0:
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="4.0.0.0" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="4.0.0.0" />
<!-- The following line was missing -->
<bindingRedirect oldVersion="3.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
至少,我希望這是一個不錯的解決方案。
編輯:如下所示,以下行更簡潔:
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
使用Visual Studio和Nuget,您需要運行此命令
安裝包Ninject.MVC3
(根據您運行的MVC版本替換3)
這將解決您的問題
Traw,是否有一個特殊的原因,你使用的是具體的實現,而不是Interfaces。 就目前而言,你直接從DI類中獲得零利益(我很驚訝你得到了任何工作)我會重構並將所有內容放在接口之后,然后將接口綁定到具體實現。
這里是一個快速拍攝的外觀:
// 'imagined' ISearchType interface
public interface ISearchType
{
int Id { get; set; }
string LastName { get; set; }
}
// 'imagined' TutorSearch concrete class
public class TutorSearch : ISearchType
{
public int Id { get; set; }
public string LastName { get; set; }
}
// your revised controller code
private readonly ISearchType _tutorSearch;
public SearchController(ISearchType searchType)
{
_tutorSearch = searchType;
}
然后,在您注冊服務(ninject)時,您需要添加:
kernel.Bind<ISearchType>().To<TutorSearch>();
這應該會讓你更進一步。 另外, var t = kernel.Get<...>
實際上什么也沒做 - 只是如果你想知道'它'發生了什么。
玩得開心...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.