11

質問を設定する前に、次のページから現在のコードを取得したことを知っておく必要があります:http: //www.strathweb.com/2012/05/using-ninject-with-the-latest-asp-net-web-api -ソース/

上記のサイトにあるIDependencyResolverアダプターを使用して、アプリケーションでASP.NETWebAPIとNinjectを使用しようとしています。

サイトに表示されているとおりにすべてのコードを作成しましたが、アプリケーションをロードすると、通常のコントローラーが失敗し、次のエラーが表示されます。

[MissingMethodException: No parameterless constructor defined for this object.]
[InvalidOperationException: An error occurred when trying to create a controller of type 'AccountManager.Controllers.HomeController'...

したがって、Ninjectは通常のコントローラーまたはWeb APIコントローラーで使用できますが、両方では使用できないようです。:(

これが私のコードです:

NinjectResolver.cs

public class NinjectResolver : NinjectScope, IDependencyResolver
{
    private IKernel _kernel;

    public NinjectResolver(IKernel kernel)
        : base(kernel)
    {
        _kernel = kernel;
    }

    public IDependencyScope BeginScope()
    {
        return new NinjectScope(_kernel.BeginBlock());
    }
}

NinjectScope.cs

public class NinjectScope : IDependencyScope
{
    protected IResolutionRoot resolutionRoot;

    public NinjectScope(IResolutionRoot kernel)
    {
        resolutionRoot = kernel;
    }

    public object GetService(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).SingleOrDefault();
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).ToList();
    }

    public void Dispose()
    {
        IDisposable disposable = (IDisposable)resolutionRoot;
        if (disposable != null) disposable.Dispose();
        resolutionRoot = null;
    }
}

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    private void SetupDependencyInjection()
    {
        //create Ninject DI Kernel
        IKernel kernel = new StandardKernel();

        //register services with Ninject DI container
        RegisterServices(kernel);

        //tell asp.net mvc to use our Ninject DI Container
        GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
    }
}

AccountingController.cs

public class AccountingController : ApiController
{
    private ICustomerService _customerService;

    public AccountingController(ICustomerService service)
    {
        _customerService = service;
    }

    // GET /api/<controller>/5
    public string Get(int id)
    {
        return "value";
    }
}
4

2 に答える 2

17

CreateKernel()への呼び出しが行われる前に、次のコード行をメソッドに挿入しますRegisterServices(kernel);

GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);

以下のコードも使用する必要があります。同じクラスで定義することをお勧めします。

public class NinjectResolver : NinjectScope, IDependencyResolver
{
    private IKernel _kernel;
    public NinjectResolver(IKernel kernel)  : base(kernel)
    {
        _kernel = kernel;
    }
    public IDependencyScope BeginScope()
    {
        return new NinjectScope(_kernel.BeginBlock());
    }
}

public class NinjectScope : IDependencyScope
{
    protected IResolutionRoot resolutionRoot;
    public NinjectScope(IResolutionRoot kernel)
    {
        resolutionRoot = kernel;
    }
    public object GetService(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).SingleOrDefault();
    }
    public IEnumerable<object> GetServices(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).ToList();
    }
    public void Dispose()
    {
        IDisposable disposable = (IDisposable)resolutionRoot;
        if (disposable != null) disposable.Dispose();
        resolutionRoot = null;
    }
}

実行すると、動作するはずです。これは私にとってはうまくいきました。あなたにとってもうまくいくことを願っています。

参考文献 :

Ninject の使用 – ASP.NET Web API コントローラーによる依存性注入

于 2012-12-01T16:04:36.790 に答える
3

Strathweb のあなたとまったく同じソリューションを使用して動作する Web API プロジェクトがあるので、プロジェクトに通常のコントローラーを追加しただけで動作します。それ自体はあまり役に立たないので、私が持っているセットアップについて詳しく説明します。

次のパッケージがインストールされています(IOC側に):

  • ニンジェクト 3.0.1.10
  • Ninject MVC 3.0.0.6
  • Ninject.Web.Common 3.0.0.7
  • ウェブアクティベーター 1.5.1

Ninject のインストール時に App_Start で自動的に作成される NinjectWebCommon.cs ファイルを使用する代わりに、Ninject に関する Global.asax.cs ファイルには何もありません。グローバル ファイルにコードが含まれているということは、Ninject がプロジェクトで正しく設定されていないことを意味するかどうかはわかりません。

NinjectWebCommon.cs のコードは次のとおりです。

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

        GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(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<IUserRepository>().To<UserRepository>().InSingletonScope();
        kernel.Bind<IUserManager>().To<UserManager>();
    }        
}

カーネルを作成するコード間で確認できるその他の違いは次のとおりです。コードはカーネルへの 2 つのバインディングを宣言します。

これが私のテストコントローラーのコードです。コンストラクターにブレークポイントを設定すると、それが取得されます。

public class TestController : Controller
{
    IUserManager _userManager;

    public TestController(IUserManager userManager)
    {
        _userManager = userManager;
    }

    //
    // GET: /Test/
    public ActionResult Index()
    {
        return View();
    }
}

これは、コントローラーと APIController の両方で機能します。

于 2012-07-26T13:43:55.843 に答える