1

ASP .NET MVC アプリケーションに奇妙な問題があります。私はいくつかのコントローラーといくつかを持っており、それはこのコントローラーIHelperの実装です。Helper以下のようにこのヘルパーを使用すると:

public ActionResult SomeAction()
{
    var hepler = new Helper();
    helper.DoStuff();
    ...
}

全て大丈夫。しかし、このヘルパーをコントローラーのプロパティとして挿入しようとすると:

public IHelper Helper { private get; set; }
...    
public ActionResult SomeAction()
    {            
        Helper.DoStuff();
        ...
    }

私のIoC構成クラスには次のものがあります。

ObjectFactory.Initialize(x =>
          {
              // Helpers
              x.For<IHelper>().Use<Helper>();              
              ...
              x.FillAllPropertiesOfType<IHelper>().Use<Helper>();
              ...
          }

問題は、IoC構成クラスのIoCパターンを使用して初期化され、各コントローラーに正常に注入された、さまざまなヘルパー、マネージャー、リポジトリ、およびその他のものをたくさん持っていることです。しかし、これを注入しようとすると、次のHelperようになります。

InvalidOperationException: An error occurred when trying to create a controller of type 'MyController'. Make sure that the controller has a parameterless public constructor.

この問題が IoC にあることはわかっています。これは、これHelperをグーグルで検索し、 IoC 構成クラスから削除して、同様に使用し、すべてが正常に機能したためです。しかし、何が問題なのか理解できませんか?以前にそのような問題を見た人はいますか?コントローラーにパラメーターのないパブリックコンストラクターがあり、コントローラープロパティの 1 つの IoC 初期化が、別のヘルパーなどですべてがうまく機能する場合に関連付けられることを確認する方法を理解することさえできません。Helpervar hepler = new Helper();

編集
_ StructureMap IoC フレームワークと ASP .NET MVC 4.0 を使用しています。

4

1 に答える 1

4

まず、ここでは実際に依存性注入を使用していません。

public IHelper Helper { private get; set; }
...    
public ActionResult SomeAction()
{
    var hepler = new Helper();
    helper.DoStuff();
    ...
}

type のプロパティを作成しました。IHelperおそらく、IoC フレームワークはそのプロパティに実装を取り込もうとしていますが、アクション メソッドではHelper、注入されたプロパティを使用せずに のインスタンスを直接インスタンス化しているだけなので、まだのHelper代わりにへの強い依存性IHelper

さらに言えば、発生するエラーは、使用している IoC フレームワークと使用している ASP.NET MVC のバージョンの両方に大きく依存する可能性があります。IoCはStructureMap のように見えますが、そうですか? MVC の場合、どのバージョンですか?

ASP.NET MVC のバージョンが異なれば、コントローラー コンストラクターでの依存関係解決の処理も異なります。たとえば、MVC 4 アプリケーションでは、 の実装を作成し、IDependencyResolverそれをコントローラーに使用できます。このようなもの:

public class DomainDependencyResolver : IDependencyResolver
{
    private readonly IoCContainer Container;

    public DomainDependencyResolver(IoCContainer container)
    {
        Container = container;
    }

    public object GetService(Type serviceType)
    {
        if (serviceType.IsAbstract || serviceType.IsInterface)
            return Container.TryGetInstance(serviceType);
        else
            return Container.GetInstance(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return Container.GetAllInstances()
                        .Where(s => s.GetType() == serviceType);
    }
}

これは汎用IoCContainerインスタンス (Common Service Locator と同様) を使用しますが、IoC 実装を直接使用したいだけであれば、おそらく問題ありません。主なことは、IoC コンテナーが要求された型の実装GetServiceGetServices返すように実装することです。次に、ASP.NET MVC を設定して、アプリケーションの起動時にコントローラーにこの依存関係リゾルバーの実装を使用します ( をGlobal.asax.cs参照)。

DependencyResolver.SetResolver(new DomainDependencyResolver(IoCContainerFactory.Current));

そこで変更する必要があるのは、IoC コンテナーへの参照だけです。私は独自のジェネリック バージョンを使用しています。これは型IoCContainerであり、 で呼び出される静的プロパティCurrentにありIoCContainerFactoryます。使用しているフレームワークを使用することになるため、依存関係リゾルバー実装のコンストラクターを変更して、渡すものと一致するようにするだけで済みます。

于 2013-03-19T11:30:53.937 に答える