2016-07-23 10 views
0

私はiocが好きです。以前は、JavaでSpringを使用していますが、現在はC#でDIを使用します。 castle.windsorが見つかりました。しかし、それは注入クラスを指示するようではありません。インタフェースを使わずにコンポーネントを注入できますか?

今、私はこれを試してみますが、失敗します....誰か、あなたはそれを修正する手助けはできますか?または、DIフレームワークとは何ですか?

Program.csの

using System; 
using Castle.MicroKernel.Registration; 
using Castle.MicroKernel.SubSystems.Configuration; 
using Castle.Windsor; 

namespace InjectionConsole 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var container = new WindsorContainer(); 
      container.Install(new MainInstaller()); 

      var service1 = container.Resolve<Service1>(); 

      service1.Say(); 

      // clean up, application exits 
      container.Dispose(); 

      Console.ReadKey(); 
     } 
    } 

    class MainInstaller : IWindsorInstaller 
    { 
     public void Install(IWindsorContainer container, IConfigurationStore store) 
     { 
      container.Register(Classes.FromThisAssembly()); 
     } 
    } 
} 

Service1.cs

using System; 

namespace InjectionConsole 
{ 
    class Service1 
    { 
     private Service2 Service2 { get; set; } 

     public void Say() 
     { 
      Console.WriteLine("Hello, I m Service 1, let me call Service 2"); 

      Service2.Say(); 
     } 
    } 
} 

Service2.cs

using System; 

namespace InjectionConsole 
{ 
    class Service2 
    { 
     public void Say() 
     { 
      Console.WriteLine("Hello, I m Service 2"); 
     } 
    } 
} 
+0

"制御の逆転"の主なポイントは、依存するクラスが実際の実装ではなくサービスのインターフェイスに依存するように依存関係を逆転させることです。インターフェイスを使用していない場合は、IOCコンテナのコアメリットと前述のパターンが排除されます。 –

答えて

0

私の答えは別のに似ているが、1つのヘア分割差で:まず

public class Service1 
{ 
    private readonly Service2 _service2; 

    public Service1(Service2 service2) { 
     _service2 = service2; 
    } 

    public void Say() 
    { 
     Console.WriteLine("Hello, I m Service 1, let me call Service 2"); 

     _service2.Say(); 
    } 
} 

は、クラス自体がかどうかをまったく同じように書き込まれますあなたはウィンザーのようなコンテナを使っています。クラスはどこかからその依存関係(Service2のインスタンス)を「取得」する必要があります。そこでコンストラクタに入れます。 Service1は、それを作成するものが何であれ、Service2を提供することを期待しています。コンテナを使用しているので、コンテナはService1を作成し、コンストラクタにはService2が必要であることがわかります。

_service2を作るreadonlyフィールドは、それが作成されています一度Service1_service2の値に対して何らさらにコントロールを持っていません(コンストラクタの実行が行われている)ことを強調しています。それは設定されており、変更することはできません。Service1内でさえも変更できません。それは重要です。なぜなら、Service1の制御はその依存関係です。我々はにそれが依存性を要求するを必要とします。これは、渡される値が何であれ、それを受け取り、それを使用します。

ここでもまた、それは毛の分割の違いです。 にならない場合は、_service2readonlyに変更しても問題ありません。しかし、これはあなたができないことを明らかにする変更することができます。

+0

ありがとうございます。仰るとおりです。しかし失敗の理由は、 "Castle.MicroKernel.ComponentNotFoundException '型の未処理の例外がCastle.Windsorで発生したことです。dll " – JonasGao

+0

登録されていないコンポーネントはどれですか? –

1

私はあなたのサービス1インスタンスでサービス2を解決したいと仮定します。あなたはコンストラクタ・インジェクションによってそれを達成することができます

using System; 

namespace InjectionConsole 
{ 
    class Service1 
    { 
     public Service1(Service2 s2) { 
      this.Service2 = s2; 
     } 

     private Service2 Service2 { get; set; } 

     public void Say() 
     { 
      Console.WriteLine("Hello, I m Service 1, let me call Service 2"); 

      Service2.Say(); 
     } 
    } 
} 
+0

あなたの答えをありがとう。しかし失敗の理由は、 "Castle.Windsor.dllで 'Castle.MicroKernel.ComponentNotFoundException'型の未処理の例外が発生しました。 – JonasGao

1

Service1Service2のクラスをpublicとマークしていないと思われます。これらのクラスはデフォルトで内部に設定されます。 Classes.FromThisAssembly()メソッドは、パブリックな型だけをロードするよう明示的に指定しない限り、パブリックな型だけを読み込みます。城ウィンザーGitHubドキュメントのページでthe docsをチェックしてください。

関連する問題