0

Castle Windsor에서 IOC 컨테이너를 만들려고합니다.이 구성은 여러 어셈블리에서 공유됩니다.성 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에서 유니티 구성 섹션을로드 (도시하지 않음) 내 공유 프로젝트 코드 내가 유니티 구성을로드 할 책임이 컨테이너 도우미가의 일환 ...으로

컨테이너를 구성하는 데 사용합니다.

이 방법의 장점은 하나의 Unity.Config가 AppDomain 내부에로드되어 (하나의 가정하에) 여러 어셈블리를 서비스 할 수 있다는 것입니다. 내 서비스 호스트에서 사용하는 어셈블리에서 GetContainer()를 호출하면 같은 유형의 등으로 채워진 컨테이너가 반환됩니다.

Castle Windsor의 유창한 구성을 사용하고 싶지만, 공유 할 수있는 구성 파일을 제공합니다. PrintService와 향후 서비스는 모두 동일한 종속성을 해결해야하며 이러한 서비스간에 유창한 구성을 반복해야 할 필요가 없습니다.

이상적으로는 내가 사용하는 모든 어셈블리에 "플로우"할 수있는 서비스 호스트 응용 프로그램에서 구성된 일종의 컨테이너가 필요합니다.

감사합니다.

+2

두 가지 다른 컨테이너 프레임 워크를 동시에 사용하는 이유는 무엇입니까? – Steven

+0

저는 성 (Castle)에서 어떻게하고 싶은지를 보여주기 위해 유니티 (Unity)에서 어떻게 수행되었는지를 보여 주려고합니다. # – Remotec

답변

0

... 여기에 전혀 도움이된다면 제가 비슷한 일을하는 방법입니다 제가 질문을 이해 할 수 없습니다 생각하지만 난 당신의 시나리오를 이해하고 생각하고

내 철학 :

응용 프로그램의 각 부분은 에 대해 알고 있고 더 많은 정보를 등록해야하므로 단일 중앙 구성 파일이 필요하지 않으며 구성 요소간에 공유되는 항목은 한 곳에서 등록되며 해당 인터페이스는 입니다. ac를 통해 어디에서나 사용할 수 있습니다. ommon 라이브러리. 그래서

의 예로 들어 보자 ... 모든

첫째, 우리는 단지 가정 해 봅시다 한 번의 구현을 등록하고 전역 사용할 IPrintService 뭔가입니다 (내 예제의 목적을 위해) 우리는 메인 어플리케이션에서 외부 모듈에 의해 구현되어야하는 다른 컴포넌트를 가지고 있다고 가정합니다.우리는, 그러므로,과 같이 공통라는 어셈블리를 만들 :

공통

public interface IPrintService 
{ 
    void Print(); 
} 

public interface IMyService 
{ 
    void DoSomething(); 
} 

지금 우리가 응용 프로그램의 주요 부분에 대해 생각하자 (어쩌면 그것은 ASP .NET 응용 프로그램, 어쩌면 온 겁니다 콘솔입니다 응용 프로그램, 정말 중요하지 않습니다). 여기에서는 컨테이너를 구성하고 가능한 모든 구성 요소를 찾도록 요청합니다.

기본 응용 프로그램

// 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>()); 
    } 
} 

그래서 지금 우리는 우리의 공유 inetrfaces와 일반 도서관과 공동의 인터페이스 구현을 등록하고 또한로드하는 주요 응용 프로그램이 : 우리는 그렇게 같은 것을 할 수 시스템의 다른 모듈.

따라서 남은 것은 인쇄 서비스를 사용하고 사용하는 것입니다. 우리는 그래서는 공통을 참조하는 세 번째 어셈블리를 만들 수 있도록 용기를 사용하는이 어디서나 작업을 수행 할 수 있습니다 (우리는 테스트 모듈을 호출합니다.

테스트 모듈

// 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

자세한 답변을 보내 주셔서 감사합니다. 이것은 확실히 도움이됩니다. 그러나, 내가하고자하는 한 가지는 PrintService와 implements가 다른 WCF 응용 프로그램을 가지고 테스트 응용 프로그램을 구현하는 것입니다. 마찬가지로, 컨테이너는 PrintService 내부의 컴포넌트로부터 "플로우"해야합니다 (즉, 객체는 분리 될 수 있어야합니다). – Remotec

+0

이 시나리오에서는 두 개의 "설치 관리자"(IWindsorInstaller 구현)를 가질 수 있습니다. 하나는 IPrintService 버전을 등록하는 테스트 응용 프로그램 내부에 있고 다른 하나는 IPrintService의 다른 버전을 등록하는 WCF 응용 프로그램 내에 있습니다. 나는 당신이 흐름에 의해 무엇을 의미하는지 모르겠다 - 일단 컴포넌트가 컨테이너에 등록되면, 속성이나 ctor 인수를 추가하거나 (또는 ​​정적 참조를 얻음으로써) (컨테이너와 상관없이) 컨테이너에 등록 된 다른 것에 대한 의존성을 가질 수있다. 컨테이너에 연결하여 필요한 경우 해당 방법으로 해결하십시오. – kmp

관련 문제