2012-04-25 2 views
1

ITagger 및 IWpfTextViewMargin이 있는데 둘 다 MEF 구성 요소로 내보내집니다. 내 여백 코드에 ITagger를 가져온 다음 해당 Tagger에서 일부 멤버를 사용하고 싶습니다.ComposeParts 메서드가 작동하지 않습니다.

이제 Margin 클래스에서 ComponentContainer를 사용한 다음 IViewTaggerProvider를 가져 왔습니다. 다음 코드를 사용하여 많은 MEF 자습서에서 찾을 수 있습니다.

[Import(typeof(IViewTaggerProvider))] 
public IViewTaggerProvider vt_provider { get; set; } 

var catalog = new AggregateCatalog(); 
catalog.Catalogs.Add(new AssemblyCatalog(typeof(TestMargin).Assembly)); 
_container = new CompositionContainer(catalog); 
//Fill the imports of this object 
try 
{ 
    this._container.ComposeParts(this); 
} 
catch (CompositionException compositionException) 
{ 
    System.Diagnostics.Trace.WriteLine(compositionException.Message); 
} 

및 내보내기 코드.

[Export(typeof(IViewTaggerProvider))] 
[ContentType... 

내 보낸 클래스는 다른 네임 스페이스이지만 동일한 어셈블리에 정의되어 있습니다.

여기 ComposeParts (this)가 ImportCardinalityMismatchException을 발생시키는 문제가 발생했습니다. 매개 변수가 인 이유를 모르겠습니다.이입니다. 카탈로그을 전달하려고했지만 예외는 없지만 가져 오기도 null입니다. 또한 debug mef failures을 언급했으며 내 보낸 클래스에 올바른 계약 이름과 수출 유형 ID가 있다고 생각합니다.


비주얼 MEFx 및 디버깅 어셈블리를 확인한 후, I는 IViewTaggerProvider도 IViewTaggerProvider의 거부의 MEF 부분 결과 인 비주얼 스튜디오 IClassificationTypeRegistryService를 가져 때문에 아마 있다는 발견.

[Primary Rejection] 
[Exception] System.ComponentModel.Composition.ImportCardinalityMismatchException: No valid exports were found that match the constraint '((exportDefinition.ContractName == "Microsoft.VisualStudio.Text.Classification.IClassificationTypeRegistryService") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "Microsoft.VisualStudio.Text.Classification.IClassificationTypeRegistryService".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected. 

그래서 한 가지 해결책은 IClassificationTypeRegistryService를 내보내는 어셈블리를 추가하는 것입니다. Visual Studio 핵심 편집기 서비스이지만 어셈블리를 내보내는 항목을 찾을 수 없습니다. 누구든지 이걸 알고 있니?

또는 더 좋은 해결책이 있습니까?

+0

수입품 목록과 수출액 목록을 작성하면 쉽게 도움이 될 것입니다. "소비"는 기본적으로'[가져 오기]'를 의미합니다. –

+0

@ jberger : 아마도 당신이 말한 것을 시도해 보았을 것입니다. 내 질문을 업데이트 한 새로운 것 같다 – Neo

+0

당신의'Margin' 클래스의 서명은 무엇입니까? –

답변

1

VisualMEFx를 사용해보십시오. 다음은 시작하는 방법에 대한 간단한 블로그 항목입니다. http://wp.me/p1HYUa-29. VisualMEFx를 사용하여 TestMargin 어셈블리를로드하고 IViewTaggerProvider가 해당 어셈블리에서 내보내 졌는지 확인합니다.

또한 ImportCardinalityMistmatch는 내보내기가 누락되었음을 의미하지 않습니다. 또한 수입을 만족시킬 수있는 수출이 너무 많아서 MEF는 사용할 수입을 선택할 방법이 없다는 것을 의미합니다. 따라서 VisualMEFx에서 구성을 검토 할 때 너무 많은 것이 있는지 확인하십시오.

이 매개 변수는 : 전화를

void Bootstrap() 
{ 
    var catalog = new AggregateCatalog(); 
    catalog.Catalogs.Add(new AssemblyCatalog(typeof(TestMargin).Assembly)); 
    _container = new CompositionContainer(catalog); 

//Fill the imports of this object 
try 
{ 
    var objectToSatisfy = this; 
    // var objectToSatifsy = new SomeOtherObjectWithImports(); 

    this._container.ComposeParts(objectToSatisfy); 
} 
catch (CompositionException compositionException) 
{ 
    System.Diagnostics.Trace.WriteLine(compositionException.Message); 
} 
} 

ComposeParts 당신은 방법에 개체를 전달합니다. 만족할 필요가있는 수입품이 있다면 MEF는 귀하가 통과하여 보았던 물건을 가져갈 것입니다. 가져 오기를 찾으면 카탈로그를보고이를 만족 시키려고 시도합니다. 원하는 객체를 ComposeParts 메소드로 전달할 수 있습니다. 그래서 두 가지 옵션을 보여주기 위해 샘플 코드를 조금 수정했습니다. 하나의 옵션은 만족되어야하는 객체를 만든 다음 컴포지션에 컨테이너에 제공하는 것입니다. 이것은 주석 처리 된 행 var objectToSatisfy = new SomeOtherObjectWithImports()에서 내가 한 것입니다. 그러나 우리가 작성하고자하는 객체가 ComposeParts과 같은 객체 인 경우가 종종 있습니다. 따라서 우리는 컨테이너에 전달할 새로운 객체를 생성 할 필요가 없습니다. 이미 객체를 가지고 있습니다. 객체에 대한 참조가 필요합니다. C#에서는 키워드 this (VB.NET에서는 Me)을 사용하여 현재 개체 인스턴스에 대한 참조를 얻을 수 있습니다.따라서 ComposeParts을 호출하는 동일한 객체에서 가져 오기를 만족하려면 ComposeParts에 대한 인수로 this 참조를 사용하면됩니다.

ComposeParts 메서드에 대한 인수는 매개 변수 배열입니다. 비공식적으로 이는 단지 container.ComposeParts(this)을 쓸 때 container.ComposeParts(new object[] { this })으로 작성된 것으로 해석된다는 것을 의미합니다. 실제로이이처럼 한 번에 MEF에 여러 개체를 전달할 수 있다는 것을 의미합니다 :

container.ComposeParts(this, objectToSatifsy, thirdObjectToCompose); 

ComposeParts를 호출하는 객체가 아무런 수입이없는 경우, 다음 인수로 this를 사용해서는 안됩니다. 대신, 작성하려는 유형의 오브젝트를 작성하여 메소드에 전달하십시오. 또한 작성하려는 모든 파트가 TestMargin 어셈블리에서 사용 가능하지 않으면 파트를 제공하고이를 AggregateCatalog에 추가하는 어셈블리에 대해 더 많은 AssemlbyCatalog를 작성해야합니다.

+0

visualMEFx를 사용해 보겠습니다. 하지만 왜 매개 변수가 _this_인지 설명해 주시겠습니까? – Neo

+0

내 호스트 클래스가 내 보낸 클래스가 아니기 때문에 VisualMEFx에 나열되지 않습니다. IViewTaggerProvider 구성 요소는 내 어셈블리에서 내 보내지 않은 서비스를 가져 오기 때문에 거부와 함께 내 보냅니다. – Neo

+0

클래스를 가져 오는 부분도 나열되어 있어야합니다. 호스트 클래스에 의해, MEF 컨테이너를 포함하는 클래스를 가리킨다면, 목록에 표시 될 수도 있고 표시되지 않을 수도 있습니다. 클래스가 가져 오거나 내보낼 지 여부에 따라 달라집니다. 나는 게시 된 코드에서 말할 수 없다. –

관련 문제