web-dev-qa-db-ja.com

Unity IoCはWeb API Controllerに依存関係を挿入しません

私はUnityを使用するのは初めてですが、私の問題は、Webサービスを呼び出すたびに、

「コントローラーにパラメーターのないパブリックコンストラクターがあることを確認してください」

複数のチュートリアルに従ってきましたが、同じ問題が引き続き発生します。

WebApiConfigクラスのRegister関数では、

var container = new UnityContainer();
container.RegisterType<IValidator, Validator>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);

ここに私のUnityResolverクラスがあります

using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;

public class UnityResolver : IDependencyResolver
{
    protected IUnityContainer container;

    public UnityResolver(IUnityContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }
        this.container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return container.Resolve(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return container.ResolveAll(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope()
    {
        var child = container.CreateChildContainer();
        return new UnityResolver(child);
    }

    public void Dispose()
    {
        container.Dispose();
    }
}

すべてのチュートリアルでこれを行う必要がないと主張されているため、コントローラーを登録していません。これが私の実際のコントローラーです

public class Controller: ApiController
{
    private IValidator _validator;

    public Controller(IValidator validator)
    {
        this._validator = validator;
    }

    [HttpPost]
    public void ReceiveIPN()
    {

    }
}

誰が私が間違っている可能性があるかについてのアイデアを持っていますか?ありがとう!

編集1:Validatorクラスの「実装」です。 Unityの問題を解決するまでここにバグを導入したくなかったので、かなり空です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


public class Validator: IValidator
{
    public bool ValidateIPN(string body)
    {
        throw new NotImplementedException();
    }
}

編集2:Fiddlerを使用してWeb APIルートを呼び出そうとすると、私は全体のエラー応答を取得します

{"メッセージ": "エラーが発生しました。"、 "exceptionMessage": "タイプ 'Controller'のコントローラーを作成しようとしてエラーが発生しました。コントローラーにパラメーターのないパブリックコンストラクターがあることを確認してください。"、 "exceptionType": "System.InvalidOperationException"、 "stackTrace": "System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)のSystem.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request、HttpControllerDescriptor controllerDescriptor、Type controllerType)でSystem.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext() "、" innerException ":{" message ":"エラーが発生しました。 "、" exceptionMessage ":"タイプ 'Project.Controller'にはデフォルトがありませんコンストラクター "、" exceptionType ":" System.ArgumentException "、" stackTrace ":" System.Linq.Expressions.Expression.New(Type type)at System.Web.Http.Internal.TypeActivator.Create [TBase](Type instanceType )System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOでSystem.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request、HttpControllerDescriptor controllerDescriptor、Type controllerType) "}}でのrActivator(HttpRequestMessageリクエスト、Type controllerType、Func`1&アクティベーター)

21

だから、何時間も頭を壁にぶつけた後、プロジェクトにOWIN/Katana Startup.csクラスがあったので、これがうまくいかないことがわかりました。ここで何が起こっているのか正確にはわからないので、これ以上の情報は素晴らしいでしょう。

基本的に、OWIN/Katanaを使用していたため、WebApiConfig.csクラスでの方法と同様に、新しいHttpConfigurationオブジェクトを作成して構成するStartup.csファイルがありました。

private void ConfigureWebApi(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
    var container = new UnityContainer();
    container.RegisterType<IValidator, Validator>();
    config.DependencyResolver = new UnityDependencyResolver(container);

    var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter().First();
    jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}

コードは最初にWebApiConfigのRegister関数を実行し、THENがStartup.csファイルで生成されたHttpConfigurationオブジェクトをオーバーライドするように見えます。それが機能するためには、ここでコンテナのセットアップを移動する必要がありました。

以前にOWINのものを表示しなかったことを申し訳ありません。これは私にとってかなり新しいものであり、関連性があるとは思いませんでした。うまくいけば、私が今まで経験してきた痛みを他の誰かが救うことを願っています。

26

Unityコンテナは、WebApiConfig.Register()メソッドのスコープでのみ定義されているため、おそらく破棄されています。コンテナをGlobalのメンバーとして定義すると、アプリの存続期間中はコンテナが維持されますが、動作するはずです。

編集:コンテナをApplication_Endに配置することも忘れないでください。

1
moarboilerplate
  • Nugetパッケージを使用して、Unity.mvc5およびUnity.WebApiをプロジェクトにインストールします
  • 以下の行に従ってfullnamespaceを指定

例:

public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();

        DependencyResolver.SetResolver(new Unity.Mvc5.UnityDependencyResolver(container));

        GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
    }
}
0