0

キャッスルウィンザーにIOCコンテナを作成しようとしていますが、その構成はアセンブリ間で共有されています。Castle Windsor IOCコンテナで流暢な構成を共有する方法

(どのような次はこれがユニティでどのように機能するかの一例である。私が何をしたいのか、それは城ウィンザーを使用して同じように動作させるためである)

私は、次のプロジェクト構成を持っている...

TestCompany.Services.Host 
    (Web project hosting a number of .svc files) 
    PrintService.svc 
    Web.Config 
    Unity.Config 

TestCompany.Services.PrintService 
    IPrintService.cs 
    PrintService.cs 

私の "PrintService"の実際の実装は、Services.Hostではなく、TestCompany.Services.PrintServiceアセンブリ内で実装されています。私の共有プロジェクトのコードの一部として

(図示せず)私はユニティ・コンフィギュレーションをロードする責任があるコンテナヘルパーを持っている...

public static IUnityContainer GetContainer() 
{ 
    // Checks for existance of container (_container == null) ommitted. 
    var section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection; 
    section.Configure(_container, name); 
    ... 
    ... 
} 

この方法はUnity.Configからユニティ構成セクションをロードしますコンテナの設定に使用します。

この方法の利点は、AppDomainが1つのUnity.Configが複数のアセンブリにサービスを提供できることです(私は推測します)。私のサービスホストによって消費されたアセンブリからGetContainer()を呼び出すだけで、同じタイプの解像度などが設定されたコンテナが返されます。

Castle Windsorの流暢な設定を使用したいのですが、共有することができる構成ファイルを作成します。 PrintServiceと将来のサービスはすべて同じ依存関係を解決する必要があり、これらのサービス間で流暢な設定を繰り返す必要はありません。

理想的には、使用するアセンブリのすべてに「フロー」できるサービスホストアプリケーションで構成された、ある種のコンテナが必要です。

ありがとうございました。

+2

なぜ2つの異なるコンテナフレームワークを同時に使用していますか? – Steven

+0

私は城で何をしたいのかをデモンストレーションしています。 # – Remotec

答えて

0

私の哲学

...私はあなたの質問を理解できないかもしれないと思うが、私は、私はあなたのシナリオを理解し、ここではそれがすべてで助け場合、私は、似た何かを行う方法であると思う:

アプリケーションの各部分は、 の内容を登録することを担当する必要があります。したがって、単一の セントラル設定ファイルは不要で、 コンポーネント間で共有されるものは1つの場所に登録され、そのインターフェイスは ac経由でどこでも利用可能オモンライブラリ。

それでは、例を見てみましょう...

まず、IPrintServiceは一度の実装を登録し、全体で使いたいものであることを私たちはちょうど(私の例の目的のために)言わせてメインアプリケーションから外部モジュールによって実装される必要のある他のコンポーネントがあることを確認します。私たちは、それゆえ、そのような一般的と呼ばれるアセンブリを作成します。

共通

public interface IPrintService 
{ 
    void Print(); 
} 

public interface IMyService 
{ 
    void DoSomething(); 
} 

今、私たちは、アプリケーションの主要部分について考えてみましょう(多分それは、ASP .NETアプリケーション、多分ジュスタのコンソールですアプリケーションは、本当に関係ありません)。ここでは、コンテナを構築し、可能なすべてのコンポーネントを見つけるように依頼します。だから今我々は共有inetrfacesとの共通ライブラリと我々の共有インターフェイスの実装を登録してもアップロードしますメインアプリケーションを持っている

主な用途

// Could be the Global.asax code behind but for simplicity this is 
// just a console application 
class Program 
{ 

    private static readonly IWindsorContainer Mycontainer 
     = BootstrapContainer(); 


    // Allow access to the raw container - this is probably a bad idea but 
    // in the rare case that you need it you can get it from here   
    public static IWindsorContainer Container { get { return Mycontainer; } } 

    private static IWindsorContainer BootstrapContainer() 
    { 
     // Here we will just install every IWindsorInstaller found in any 
     // assembly in the same folder as the application (so no need for 
     // references or anything). 
     var c = new WindsorContainer(); 
     string folder = Path.GetDirectoryName(
      Assembly.GetExecutingAssembly().Location); 
     c.Install(FromAssembly.InDirectory(new AssemblyFilter(folder))); 
     return c; 
    } 
} 

// Here is the print service implementation 
public class MyPrintService : IPrintService 
{ 
    public void Print() 
    { 
     // Print! 
    } 
} 

// This is the installer for the main module - here we are saying exactly 
// what is implementing the interface 
public class MainApplicationInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, 
         IConfigurationStore store) 
    { 
     container 
      .Register(Component 
          .For<IPrintService>() 
          .ImplementedBy<MyPrintService>()); 
    } 
} 

:私たちはそうのようなことを行うことができますシステム内の他のモジュール。

残っているのは、その印刷サービスを消費して使用することだけです。私たちは、その者は、のみ共通を参照する第三のアセンブリを作成してみましょうコンテナを使用しているこれのどこを行うことができます(私たちは、テストモジュールを呼び出します。

テストモジュール

// This installer installs just the things inside this module since that 
// is all it knows about but those things can use things that are 
// registered in the container by anybody. 
public class TestModuleInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, 
         IConfigurationStore store) 
    { 
     container 
      .Register(Component 
          .For<IMyService>() 
          .ImplementedBy<MyServiceThatDoesSomething>()); 
    } 
} 

public class MyServiceThatDoesSomething : IMyService 
{ 
    private readonly IPrintService _printService; 

    public MyServiceThatDoesSomething(IPrintService printService) 
    { 
     _printService = printService; 
    } 

    public void DoSomething() 
    { 
     // Use the print service! 
     _printService.Print(); 
    } 
} 

を最後にすべてをコンパイルしてコピー

Container.Resolve<IMyService>().DoSomething(); 

をそして魔法が起こるまあ、いくつかのメインアプリケーションと同じフォルダにテストモジュールは、その後、メインから、あなたはこれを行うことができます!コードが実行され、印刷サービスが何も知らないにもかかわらず、モジュールからクラスによって呼び出されることがわかります。

とにかく、多分それはちょっとした助けになるかもしれません。

+0

詳細を確認していただきありがとうございます。これは確かに多くの助けになります。しかし、私が探していることの1つは、PrintServiceのインプリメンテーションと別の実装を持つテストアプリケーションを持つWCFアプリケーションを用意することです。同様に、PrintService内のコンポーネントからも、コンテナは「フロー」(つまり、オブジェクトは解決可能でなければならない)でなければなりません。 – Remotec

+0

このシナリオでは、2つの "インストーラ"(IWindsorInstallerの実装)を用意できます.1つはIPrintServiceの1つのバージョンを登録するテストアプリケーションの中に、もう1つはIPrintServiceの異なるバージョンを登録するWCFアプリケーションの中にあります。私はあなたがフローによって何を意味するのか分かりません - コンポーネントがコンテナに登録されると、プロパティやctorの引数を追加するだけで(アセンブリに関係なく)コンテナに登録されている他のものに依存することができます必要に応じてその方法で解決してください)。 – kmp

関連する問題