4

最近、初めてIoCコンテナーを使い始めましたが、それを使用するためのベスト プラクティスについての教育を受けていません。より具体的には、Unityを C# .NET プロジェクトで使用していますが、 Prismに付属していたので使い始めました。

コンテナを使用して「最上位」オブジェクトを解決すると、コンテナに基づいて注入された正しいオブジェクトが取得されます。ただし、子と子の子を持つオブジェクトがあり、IoC コンテナーからのデータがずっと必要であるが、その間ではない場合、ベスト プラクティスを明確に見ることができません。通常、IoC コンテナーの使用をどのように整理しますか?

最初は、最上位のコンテナーから必要なデータを抽出してこのデータを渡すのではなく、必要な場所にコンテナーを渡すと思います。しかし、注入されたインターフェースに加えて他の特定のデータを取るオブジェクトに到達すると、再び問題が発生します。オブジェクトを解決した後、プロパティまたは init-method を介してこれらを注入したくありません。

これが十分に明確であることを願っていますが、架空の (そして少しばかげた..) 例を見てみましょう。

class Employee
{
    private ICommands _commands; 
    priate List<Customer> _customers = new List<Customer>(); 
    public Employee(ICommands commands)
    {
        _commands = commands; 
    }
    public void AddCustomer(string customerName)
    {
        var customer = new Customer(customerName, _commands); 
        _customers.Add(customer); 
    }
}

class Customer 
{
    private string _name; 
    private ICommands _commands; 
    priate List<Case> _cases = new List<Case>(); 
    public Customer(string, name, ICommands commands)
    {
        _name = name; 
        _commands = commands; 
    }
    public void AddCase()
    {
        var case = new Case(_commands); 
        _cases.Add(case); 
    }
}

class Case    {
    private ICommands _commands; 
    public Customer(ICommands commands)
    {
        _commands = commands; 
    }
    public void TriggerCommands()
    {
        _command.TriggerSomething(); 
    }
}

したがって、この例はあまり意味がありませんが、本質は、私がしなければならないことと同じです。ViewModel クラスに渡すアプリケーション コマンドがいくつかあります。それらのいくつかは、何かを表示するコマンドをトリガーできる必要があるためです。また、一部のクラスで必要になる可能性がある共通ストレージなどもありますが、現在は中間クラスに渡されて格納されています。コマンドのみの場合、コマンドまたはコンテナを保存しても大したことはありませんが、典型的な IoC の使用法では、代わりに IoC コンテナを渡し、これを後でオブジェクトを解決するために使用しますか? また、顧客名などの特定のデータについてはどうでしょうか? これを Resolve() に渡すことはできないので、後で注入する必要がありますか?

申し訳ありませんが、これは私ができる限り短いものでした。同じ長さの回答は必要ありません;-) ..ただ; IoC コンテナーでこのようなことを行うベスト プラクティスは何ですか?

4

4 に答える 4

3

私はあなたの質問を理解しているかどうか確信が持てません。しかし、コンテナを渡す必要はまったくないと思います。コンテナーのラッパー クラスを作成する方がはるかに簡単です。例えば:

public class IoCContainer
{
  private static ContainerType = null;

  public static ContainerType Instance 
  {
    get 
    {
      if (_container == null)
      {
        string configFileName = ConfigurationManager.AppSettings[ConfigFileAppSettingName];
        _container = new WindsorContainer(new XmlInterpreter(configFileName));
      }

      return _container;
    }
  }
}

これで、コードのどこでもこれを呼び出すことができます。

IoCContainer.Instance.Resolve<IAwesomeService>(); 

これは役に立ちますか?

于 2009-10-23T11:10:28.843 に答える
2

これがあなたの質問に答えるかどうかはわかりませんが、Unityコンテナー(私が思う他のIoCエンジンにも適用可能)を使用してアプリケーションを操作する良い方法は次のとおりです。

  • 必要なすべての依存関係がコンストラクターで指定されるようにクラスを設計します。このように、新しいオブジェクトを作成する必要がない限り、Unityを明示的に処理する必要はありません。
  • クラス内に新しいオブジェクトを作成する必要がある場合は、コンストラクターでUnityコンテナー自体も(への参照として IUnityContainer)渡し、メソッドを使用してすべての新しいオブジェクトインスタンスを作成しますResolve 。登録されておらず、依存関係もないオブジェクトの場合でも、コンテナは適切なインスタンスを提供し、後でクライアントコードを変更せずに、以前に登録されていないタイプを登録することを決定できます。
  • 解決されたオブジェクトに明示的な値を渡すことに関しては、タイプを登録するときに具象注入メンバーを指定できます(クラスのInjectionMembersパラメーターを参照)。RegisterType
于 2009-10-23T11:17:17.380 に答える
0

特定のコンテナーで初期化できる静的クラス IoC を定義し、Resolve、Resolve(...) などのメソッドを実装して、実際の作業をコンテナー インスタンスに委任します (このインスタンスをフィールドまたはプロパティ)。この方法では、何も渡す必要はありません。使用するだけです

IoC.Resolve<SomeType>();

コードのどこにでも。

特定のデータに関して: 一部のコンテナーはパラメーターを取り、このパラメーターに応じて解決します (Autofac にはこの種の機能があります)。または、一連のパラメーター (顧客名など) を受け取り、対応するオブジェクト インスタンスを返すメソッドを持つファクトリ クラスをいつでも作成できます。

于 2009-10-23T11:40:07.357 に答える