2009-09-22 5 views
2

내 비즈니스 로직 구성 요소가 내 양식/컨트롤 클래스 중 하나에 추가 될 때 서비스를 쿼리 할 수있게하려고합니다. 예를 들어, 일부 비즈니스 로직을 캡슐화하는 내 라이브러리에 ClientManager 클래스가있을 수 있습니다. 작동해야하는 데이터를 쿼리하려면 ILoginManager 인스턴스가 필요합니다.WinForms 응용 프로그램의 종속성 삽입을 위해 System.ComponentModel에서 서비스 로케이터 구현을 어떻게 사용합니까?

콘크리트 ILoginManager 인스턴스는 WinForms 응용 프로그램에서 생성됩니다 (예 : 싱글 톤). ClientManager 구성 요소를 양식에 놓으면 구성 요소에서 ILoginManager 인스턴스를 자동으로 사용할 수있게됩니다.

내가 this article on lightweight containers에서 이해하는 것과

, 나는의 getService를 사용하여이를 달성 할 수 : 독립형으로

public class MyContainer : Container 
{ 
    ServiceContainer svc; 

    public MyContainer() { 
     svc = new ServiceContainer(); 
     svc.AddService(typeof(ILoginManager), GlobalAppStuff.LoginManager); 
    } 

    protected override object GetService(Type service) { 
     return svc.GetService(service); 
    } 
} 

:

public class ClientManager : Component 
{ 
    public ClientManager() {} 
    public ClientManager(IContainer container) { 
     container.Add(this); 
    } 

    public ILoginManager User 
    { 
     // would really be cached in a private field 
     get { return GetService(typeof(ILoginManager)) as ILoginManager; } 
    } 

    // does something that requires the User property to be set 
    public void DoSomething(); 
} 

그때 내 인스턴스를 반환의 getService을 무시 컨테이너를 것 솔루션,이 잘 작동하지만 디자이너가 항상 기본 System.ComponentModel.Container 컨테이너를 생성하고이를 서비스에 삽입하는 방법을 모르기 때문에이 컨트롤을 디자인 할 수있는 컨트롤로 통합하는 방법을 알아낼 수 없습니다.

MSDN 설명서는 이러한 개념을 실제로 어떻게 사용해야하는지 모호합니다. 디자이너 친화적 인 ComponentModel 클래스를 사용하여이 작업을 수행하는 간단한 방법이 있습니까?

답변

2

DI 용으로 System.IServiceProvider를 사용하지 마십시오. 주로 디자인 타임 용도로 사용됩니다. IComponent 구현의 경우 VS 디자이너는 전체 IServiceProvider 메커니즘이 작동하도록하는 Site 속성에 값을 할당하지만 런타임에이 속성이 null이됩니다. 즉, GetService에 대한 모든 호출이 실패하게됩니다. .

당신은 등 성 윈저, StructureMap와 같은 적절한 DI 컨테이너를 사용하여 더 나을 것 성이 생성자 주입을 사용하기 때문에 나 폼에 내 구성 요소를 드래그 할 수 없습니다

+1

. StructureMap은 정적 객체를 사용합니다. 정적 객체는 특히 StructMap에 내 객체를 연결하기 때문에 좋아하지 않습니다. 기본 .NET 구성 요소처럼 보이지만, 필자가 필요로하는 대부분의 기능을 이미 지원합니다. 디자이너와 함께 사용하는 데 어려움이 있습니다. –

+0

아마도,하지만 어렵더라도 디자이너에서만 작동합니다. 런타임시 IComponent.Site는 null이지만 IServiceProvider 구현을 제공하는 ISite 값이므로 런타임에 작동하지 않습니다. –

+0

그게 전부인지 확실하지 않습니다. 디자이너가 ISite를 설정하지 않습니다. 컨테이너가 않습니다. 디자이너는 디자인 타임에 자체 System.ComponentModel.Design.DesignerHost 컨테이너를 사용합니다. 하나는 런타임에 자신의 컨테이너를 제공 할 수 있어야하며 Visual Studio는 실제로 그 코드를 생성하지만 생성하는 컨테이너 유형을 재정의하는 방법을 알지 못합니다. –