質問

MicrosoftのUnity FrameworkでC#を使用しています。この問題を解決する方法はよくわかりません。それはおそらく、私が団結した私の理解の欠如と関係があるでしょう。

私の問題は、次の例コードを使用して要約できます。

class Train(Person p) { ... }

class Bus(Person p) { ... }

class Person(string name) { ... }

Person dad = new Person("joe");
Person son = new Person("timmy");

バスの解決方法を呼び出すとき、「ティミー」という名前の「息子」が注入されていることを確認するにはどうすればよいですか。

私は多分名前が付けられたインスタンスを使うと思っていますか?しかし、私は途方に暮れています。どんな助けも感謝します。

余談ですが、私はむしろIpersonインターフェイスを作成したくありません。

役に立ちましたか?

解決

これを解決する1つの方法は、指定された登録で注入コンストラクターを使用することです。

// Register timmy this way  
Person son = new Person("Timmy");  
container.RegisterInstance<Person>("son", son);  

// OR register timmy this way  
container.RegisterType<Person>("son", new InjectionConstructor("Timmy"));  

// Either way, register bus this way.  
container.RegisterType<Bus>(new InjectionConstructor(container.Resolve<Person>("son")));  

// Repeat for Joe / Train

他のヒント

それぞれ「Joe」と「Timmy」という名前の依存関係として登録しない限り、「ティミー」がSchoolbusに注入されるかどうかはわかりません。実際、名前のない依存関係と同じクラスの2つのインスタンスを登録しようとすると、あいまいなセットアップがあり、解決できなくなります。 Person まったく。

一般的に、多くの名前のインスタンスを登録する必要がある場合、おそらく間違った方法でDIについて進んでいるでしょう。 DIの主な考え方は解決することです ドメインサービス より多い ドメインオブジェクト.

DIの主な考え方は、解決できるメカニズムを提供することです 要約タイプ (インターフェイスまたは抽象クラス) コンクリートタイプに. 。あなたの例には抽象的なタイプがないので、それはあまり意味がありません。

マーク・シーマンはそれを正しくしました。そして、私はあなたの混乱に同情します。自動依存噴射容器を使用することを学んだとき、私は自分でそれを経験しました。問題は、オブジェクトを設計および使用するための多くの有効で合理的な方法があることです。しかし、これらのアプローチの一部のみが、自動依存関係のインジェクションコンテナで動作します。

私の個人的な歴史:私は、UnityやCastle Windsorコンテナなどの制御容器の反転を使用する方法を学ぶずっと前に、オブジェクトの構築と制御の反転のOO原則を学びました。私はこのようなコードを書く習慣を取得しました:

public class Foo
{
   IService _service;
   int _accountNumber;

   public Foo(IService service, int accountNumber)
   {
      _service = service;
      _accountNumber = accountNumber;
   }
   public void SaveAccount()
   {
       _service.Save(_accountNumber);

   }
}
public class Program
{
     public static void Main()
     {
        Foo foo = new Foo(new Service(),1234);
        foo.Save();
     }
}

この設計では、私のFooクラスは、アカウントをデータベースに保存する責任があります。それを行うにはアカウント番号と汚い仕事をするサービスが必要です。これは、上記のコンクリートクラスに多少似ており、各オブジェクトはコンストラクターに一意の値を取得します。これは、独自のコードでオブジェクトをインスタンス化するときに正常に機能します。適切な値を適切なタイミングで渡すことができます。

しかし、自動依存噴射容器について学んだとき、私はもはや手作業でfooをインスタンス化していないことがわかりました。コンテナは、私のためのコンストラクターの議論をインスタンス化します。これは、iServiceのようなサービスにとって非常に便利でした。しかし、それは明らかに整数や文字列などではそれほどうまく機能しません。そのような場合、デフォルト値が提供されます(整数の場合はゼロなど)。代わりに、私はアカウント番号、名前などのようなコンテキスト固有の値を渡すことに慣れていました...そのため、このようにコーディングとデザインのスタイルを調整する必要がありました。

public class Foo
{
   IService _service;
   public Foo(IService service)
   {
      _service = service;
   }
   public void SaveAccount(int accountNumber)
   {
       _service.Save(accountNumber);

   }
}
public class Program
{
     public static void Main()
     {
        Foo foo = new Foo(new Service());
        foo.Save(1234);
     }
}

両方のFooクラスは有効な設計であるように見えます。しかし、2番目は自動依存噴射で使用でき、1つ目はそうではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top