2017-03-14 2 views
2

문제

나는 윈폼 응용 프로그램 MEF와 플러그인을 구현하고있어 내가 이해가 안 조성물과 몇 가지 동작을 알았어 야와 무슨 일이 일어나고 있는지 이해하는 데 도움이됩니다.MEF는 - 컨테이너와 구성

그냥 길에서 그걸 얻기 위해, 내가 .NET ATL 촌놈의 일종으로 4

와 MEF를 사용하고, 닥터, 여기에 내가 용기와 구성에 관해서에 명확하지 않다 무엇인가 :

  1. 내가, 자체 내 보낸 일부 클래스의 내부에 컨테이너를 구성하고 ComposeParts(this)를 호출하면 해당 클래스의 기존 인스턴스가 컨테이너에 추가 또는 다른 인스턴스가 생성된다?
  2. GetExportedValue<T>() 메서드를 사용할 때 반환 된 파트가 이미 작성되었거나 가져 오기가 채워져 있어야합니까? 아니면 명시 적으로 파트를 작성해야합니까? 첫 번째 질문에 대해서는

... 각 질문에 대한 자세한 내용은 읽어

배경

, I는 "정상"애플리케이션 된 UserControls를 호스팅 할 패널이있는 기본 응용 프로그램 양식을 플러그인으로부터의 usercontrols. 이 주요 응용 프로그램 양식은 ​​IHostingForm이라는 인터페이스를 구현하여 일부 기능을 플러그인에 제공합니다. 이 주요 신청서 양식은 IHostingForm 인터페이스를 통해 자신을 수출하며 수입이 필요합니다. 여기에 코드입니다 : 그 자체를 수출하는 방법을 위의 코드 조각에서

[Export(typeof(IHostingForm))] 
public partial class frmMain : RibbonForm, IHostingForm 
{ 
    //public/private form methods here... 
    private CompositionContainer _container; 

    //An import that needs to be filled. 
    [ImportMany] 
    public IEnumerable<Lazy<IAddInController, IAddInControllerMetadata>> AddInControllers; 

    public frmMain() 
    { 
     //Init code here omitted to save space... 

     //Setup the container 
     var catalog = new AggregateCatalog(); 
     catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly)); 
     //Temporary location while testing... 
     catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath)); 

     _container = new CompositionContainer(catalog); 
     try 
     { 
      //Is the current instance of the class (this) added to the 
      //container or does the container construct its own instance? 
      _container.ComposeParts(this); 
     } 
     catch (CompositionException ex) 
     { 
      //Error catching code omitted... 
     } 
    } 

    //IHostingForm implementation 
    public void AddTabToTabBar(string tabText) 
    { 
     RibbonTab rt = new RibbonTab(tabText); 
     //Some more init code here which I'm leaving out to save space... 
     this.ribbonBar1.CommandTabs.Add(rt); 
    } 
    //etc... 
} 

공지 사항뿐 아니라 생성자에서 ComposeParts(this) 호출? 이렇게하면 양식의 인스턴스가 별도로 생성되거나 ComposeParts(this)이 이미 존재하는 인스턴스를 사용하고 컨테이너에 추가하기에 충분한 지 알 수 있습니까?

이것은 두 번째 질문입니다. 위에서 사용하고있는 구성 방법이 맞는지 아닌지 잘 모르겠습니다. 응용 프로그램의 프로그램 클래스에서 컨테이너를 만들려고했는데 이해가되지 않는 다른 동작을 발견했습니다. 나는이 같은 형태의 클래스 중 및 프로그램에 컨테이너 초기화 코드 이동 :

static class Program 
{ 
    internal static CompositionContainer _container; 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     //Setup the container 
     var catalog = New AggregateCatalog(); 
     catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly)); 
     catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath)); 

     _container = new CompositionContainer(catalog); 

     IHostingForm frm = _container.GetExportedValue<IHostingForm>(); 
     //If I don't call this, the form's imports don't get satisfied 
     _container.CompostParts(frm); 
     Application.Run((Form)frm); 
    } 
} 
MSDN에있는 문서를 바탕으로

the answer to this question을, 나는 GetExportedValue<T>() 방법은 주어진의 수출을 인스턴스화 할 것이라는 인상이었다 유형을 작성하고 컨테이너를 작성했기 때문에 (또는 종속성을 만족 시키십시오) 컨테이너에서 나오기 때문입니다. 그러나 테스트를 통해, 컨테이너에서 부품을 가져온 후에 가져온 부품을 채우기 위해 컨테이너를 명시 적으로 말해야한다고 생각합니다. 이것은 내가 지금까지 읽은 것과 모순되는 것 같습니다.

여러 질문인지 확실하지 않았습니다. 그들이 헤어질 필요가 있으면 알려주세요.이 질문을 편집하고 다른 질문을 만들어 드리겠습니다. 그러나 나에게있어서 그들은 용기와 구성에 어떤 일이 벌어지고 있는지에 대한 나의 이해가 부족하다는 점에서 관련이있는 것으로 보인다.

답변

1

위의 스 니펫에서 어떻게 자체를 내보내는 지 알지만 생성자에서 ComposeParts (this)도 호출합니까?이것은 폼의 분리 된 인스턴스를 만들거나 이미 존재하는 인스턴스를 사용하고 그것을 컨테이너에 추가하는 것을 알기에 충분히 똑똑한 ComposeParts (이)입니까?

'충분히 똑똑합니다'라고 말한대로 할 것입니다. ComposeParts(this)this에 대해 Import을 만족해야하는지 먼저 확인합니다. 그런 다음 Export과 일치하는 유형/유형을 찾고 해당 매개 변수없는 생성자를 호출합니다. 인스턴스가 작성된 후 해당 유형의 Import을보고 다시 시작합니다.

이제 어떤 점에서 이미 생성 된 유형을 묻는 Import 지시문을 발견하면 두 번째 인스턴스를 생성하는 대신 이미 존재하는 인스턴스를 Import 지시문에 제공합니다.

몇 가지 유형에 매개 변수없는 생성자를 추가하고 거기에 중단 점을 넣어 쉽게 확인할 수 있습니다.

이 두 번째 질문에 관해서는, 내가 별도의 질문을 제안 - 이 유형의 Export 속성을 광고하지만 내가 아는 한, ComposeParts 이전에 사용하지 않은/알 수없는 부분을 찾거나 인스턴스화합니다 /이 호출 된 객체 에서 - 귀하의 경우에 [Export(typeof(IHostingForm))]. 반면에 GetExportedValue은 이미 존재하는 부분을 검색하고 하지가 새로운 부품을 인스턴스화 - Import이 부분 X를 요구하지만 그런 부분은 이전에 ComposeParts 또는 SatisfyImports에 의해 생성되지 않은 경우 의미 - 그 Import 뒤에 프로퍼티/필드에 남아있을 것입니다 불만족/null.