37

mvc4 rcアップデートをインストールしたばかりで、運が悪かったAPIアプリケーションを構築しようとしています。

ninjectを使用していますが、コントローラーをロードできません。エラーが発生し続ける

タイプ'Api.Controllers.ConsumerController'にはデフォルトのコンストラクターがありません

私はMVCに非常に慣れておらず、インジェクションを使用しているので、ご容赦ください。

nugetを介して作成されたデフォルトのバインディングに特別なことは何もしていません

 public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    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)
    {
        kernel.Bind<IConsumerRepository>().To<ConsumerRepository>();
    }        
}

私のコントローラーは次のようになります

   private readonly IConsumerRepository _repository;

    public ConsumerController(IConsumerRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    public IQueryable<Consumer> Get(Guid id)
    {
        return _repository.Get(id).AsQueryable();
    }

APIコントローラーをninjectで動作させるには何をする必要がありますか?

これが単純なものならごめんなさい

私はあなたの提案マイケルを試しましたが、webcommon.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);
        GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(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)
    {
        kernel.Bind<IConsumerRepository>().To<ConsumerRepository>();
    }

エラーが発生する

var kernel = new StandardKernel();

と呼ばれる

アセンブリ'Ninject.Web.WebApi、Version = 3.0.0.0、Culture = neutral、PublicKeyToken=c7192dc5380945e7'のタイプ'Ninject.Web.WebApi.Filter.DefaultFilterProvider'のメソッド'GetFilters'には実装がありません。

私は何が欠けていますか?

4

11 に答える 11

60

これについてBradWilsonに聞いたところ、MVC4RCで変更されました。

GlobalConfiguration.Configuration.ServiceResolverはGlobalConfiguration.Configuration.DependencyResolverに移動されました

この実装を使用して、WebAPIのNinjectDependencyResolverを作成します: https ://gist.github.com/2417226

NinjectWebCommon.csの場合

// Register Dependencies
RegisterServices(kernel);

// Set Web API Resolver
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
于 2012-06-01T17:50:17.870 に答える
6

この一般的なエラーメッセージ

タイプ'Api.Controllers.ConsumerController'にはデフォルトのコンストラクターがありません

コンストラクターをパブリックにしない場合、または引数が欠落しているためにIoCコンテナーで依存関係を解決できない場合にも発生する可能性があります。

エラーメッセージは控えめに言っても誤解を招きます。

于 2012-08-15T10:07:00.030 に答える
6

NuGetパッケージWebApiContrib.IoC.Ninjectをインストールし、次のコード行をNinjectWebCommon.csに追加できます。

GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
于 2013-10-02T22:27:39.573 に答える
1

検索中にここに着陸した人のために'...デフォルトのコンストラクターがありません'サイレントに失敗した構成をデバッグする簡単な方法を探しています:

  1. コンストラクターを呼び出すことができるようになるまで、コンストラクターによって挿入されたオブジェクトを削除します
  2. 以前に注入された、現在は初期化されていないオブジェクトのそれぞれについて、次を使用して呼び出します。

ServiceLocator.Current.GetInstance<[OBJ-TYPE]>()

問題のあるオブジェクトは、説明メッセージを含むActivationExceptionを引き起こします。あなたは行くべき何かを持っているでしょう。

修正後のServiceLocatorへの呼び出しを削除することを忘れないでください。つまり。これは、デバッグ以外でサービスロケーターのアンチパターンを使用することをお勧めしません。

于 2016-02-24T14:16:54.800 に答える
0

コンテナをfraweworkに登録しましたか?私はautofacを使用することを好みます。これは、APIでautofacを使用する方法の例です。http://alexmg.com/post/2012/03/08/Autofac-ASPNET-Web-API-%28Beta%29-Integration.aspx

また、Mark Seemanは、WebAPIを使用したDI全般に関する優れた投稿をしています。

http://blog.ploeh.dk/2012/03/20/RobustDIWithTheASPNETWebAPI.aspx

Ploehから:

GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
    t => this.container.Kernel.HasComponent(t) ?
        this.container.Resolve(t) :
        null,
    t => this.container.ResolveAll(t).Cast<object>());

上記はglobal.asaxで実行する必要があります

于 2012-06-01T13:34:22.023 に答える
0

うまくいけば、これは他の誰かを助ける...

私も同じ問題を抱えていましたが、コントローラーの初期化を担当するアセンブリの登録を担当するクラスを移動することに関連していました。Webからフレームワークプロジェクトに移動しました。

Autofacを使用しますが、他のコンテナにも同じことが当てはまります。

呼んでいた:

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

これは、Webアプリケーション内では正常に機能しますが、実行中のアセンブリにコントローラーが含まれなくなったため、フレームワークプロジェクトに移動すると、上記の例外が発生しました。

代わりに、次のように更新する必要がありました。

builder.RegisterApiControllers(Assembly.GetCallingAssembly());
于 2012-08-20T02:13:25.993 に答える
0

Ninjectは、IOCの依存関係が正しく設定されていない場合に一般的に発生するように、例外をスローしなかったようです。代わりに、確かに登録したWebAPI依存関係リゾルバーを登録していないように見えました。これがこの問題に対する私の解決策でしたが、私が見つけたものから、それは多くの異なるタイプのセットアップの問題である可能性があります。依存関係チェーンのすべてを再確認するだけです。うまくいけば、それは誰かを助けます!

コントローラー:

public class ContestsController : ApiController
{
    //Ninject wouldn't inject this CTOR argument resulting in the error
    public ContestsController(IContestEntryService contestEntryService)
    {

依存関係:

public class ContestEntryService : IContestEntryService
{

    public ContestEntryService(IContestsContext contestsContext)
    {

誤った構成:

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IContestsContext>()
              .To<ContestsContext>()
              .InRequestScope();

        kernel.Bind(x =>
            x.FromAssembliesMatching("MyNameSpace.*")
             .SelectAllClasses()
             .BindAllInterfaces()
         );

正しい構成:

    private static void RegisterServices(IKernel kernel)
    {
         kernel.Bind(x =>
            x.FromAssembliesMatching("MyNameSpace.*")
             .SelectAllClasses()
             .BindAllInterfaces()
         );

         kernel.ReBind<IContestsContext>()
              .To<ContestsContext>()
              .InRequestScope();

一般的に、Ninjectはこの種のエラーを報告するのに非常に優れているので、私は本当にこれでループに陥りました!

于 2013-09-06T18:17:43.540 に答える
0

私はその古い投稿を知っていますが、私はいくつかのリンクで解決策を見つけたので、ここで共有します。それが役に立てば幸い。

http://weblogs.asp.net/hajan/archive/2013/03/16/quick-tip-how-to-make-ninject-work-with-asp-net-web-api.aspx?CommentPosted=true#コメントメッセージ

于 2013-09-27T04:11:03.273 に答える
0

それでも問題が発生する場合は、何らかの理由でninjectがMVC 4で期待どおりに機能しないことを聞いてください。WebAPIで、このコードを記述する必要があります。

public DefaultController() : base() { }  

これにより、デフォルトコンストラクタがないというエラーが削除され、getメソッドからデータを取得する必要がある場合は、次のコードを記述します。

public IEnumerable<YourModelGoesHere> Get() 
{
    return context.YourData;  
} 

ここでもdbクラスにアクセスする必要があることに注意してください。たとえば、次のようになります。

DefaultConnection context = new DefaultConnection(); 
于 2014-02-13T00:53:22.690 に答える
0

Ninject.MvcXXXパッケージをインストールするだけです。ここで、XXX-MVCのバージョン...

于 2015-01-14T14:08:35.980 に答える
0

このエラーメッセージも表示されましたが、インターフェイスの1つが実際にはどのクラスにも実装されていないことがわかりました(クラス宣言に追加するのを忘れました)。

于 2015-02-24T18:11:17.757 に答える