14

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拡張機能の内部で何が起こっているのかよくわからないため、どの時点でコントローラーのバインドが失敗しているのかわかりません。

何を見るべきかについてのポインタは非常にありがたいです、ありがとう。

4

3 に答える 3

17

そのため、かなりの時間を必死にいじくり回した後、ようやく問題を見つけました。私は 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" />
于 2013-01-16T08:49:04.277 に答える
6

Visual Studio と Nuget を使用して、このコマンドを実行する必要があります

インストールパッケージ Ninject.MVC3

(実行している MVC バージョンに応じて 3 を置き換えます)

これで問題が解決します

于 2014-09-07T18:22:42.790 に答える
1

Traw さん、インターフェイスではなく具体的​​な実装を使用している特定の理由はありますか?? 現状では、クラスを直接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<...>「それ」に何が起こったのか疑問に思っている場合に備えて、実際には何もしません。

楽しむ...

于 2013-01-15T18:15:49.340 に答える