2009-05-05 2 views
2

MEF 내보내기에 공유 부분 생성 정책을 사용하려고합니다. 그러나 나는 생각했던대로 작동하지 않는 것 같습니다. 내 응용 프로그램에서 두 번 컴포지션을 할 때마다 개체의 새로운 복사본을 얻을. 객체 인스턴스에 인스턴스 카운터를 추가하여 증명했습니다.MEF 생성 정책

static int instCount = 0; 

    public FakeAutocompleteRepository() 
    { 
     instCount++; 
     ... 
    } 

그리고 디버그로 모두 실행합니다. 사실 내가 조성물을 할 두 번째 내가 instCount = 2. 수출 섹션으로 FakeAutocompleteRepository의 새 복사본을 얻을 수는

[PartCreationPolicy(CreationPolicy.Shared)] 
[Export(typeof(IAutocompleteRepository))] 
[ExportMetadata("IsTesting", "True")] 
class FakeAutocompleteRepository : IAutocompleteRepository 
{ ... } 

는 subsiquent 요청에 대해 동일한 인스턴스를 얻는 데 약간의 트릭이 거기에 포함? 내가 작곡 도중하는 일이라면 이것이 내가하는 일이다.

var catalog = new AggregateCatalog(); 
       catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); 
       catalog.Catalogs.Add(new DirectoryCatalog(".")); 
       var container = new CompositionContainer(catalog); 
       var batch = new CompositionBatch(); 
       batch.AddPart(this); 
       container.Compose(batch); 


       if (null != ConfigurationSettings.AppSettings["IsTesting"] && bool.Parse(ConfigurationSettings.AppSettings["IsTesting"])) 
        repository = container.GetExports<IAutocompleteRepository>().Where(expDef => expDef.Metadata.Keys.Contains("IsTesting")).Single().GetExportedObject(); 

기본적으로 나는 시험 중에 특정 작곡을 강요하려고 노력하고있다. 이 작곡을 단원 단위로 테스트 할 때 더 좋은 아이디어가 있다면, 나는 모두 귀를 기울입니다.

답변

3

코드에 두 개 이상의 부분이 생성되는 것을 특별히 보지 못합니다. 각 작품에 대해 다른 컨테이너를 만들고 있습니까? 그렇다면 별도의 인스턴스를 얻는 것입니다.

일반적으로 구성 및 단위 테스트를 결합하는 방법에 대해서는 here에 대한 일부 논의가 있습니다.

+0

나는 매번 새로운 컨테이너를 만들고 있습니다. 활성 컨테이너를 쿼리하는 방법이 있습니까? 아니면 응용 프로그램 인스턴스를 어딘가에 만들어야합니까? – stimms

+0

활성 컨테이너를 쿼리하는 방법이 없습니다. 당신이해야 할 일에 대한 조언을 해주기 위해서 당신의 신청서에 대해 더 많이 이해해야합니다. 다양한 작곡은 무엇입니까? –

+0

할 수있는 일 호스트에서 컨테이너를 내보내고 사용할 때마다 가져옵니다. 나는 그것을하지 않았지만 MefShapes 게임 예제에서 본 것 같아요. –

2

단위 테스트를 위해 내가 한 것은 구성을 피하는 것이 었습니다. 예를 (내가 여기에 WPF와 MVVM을 사용하고 있습니다),의는이 뷰 모델 테스트하고 싶은 말은하자의 경우 : 내가 단위 테스트를 할 때마다 본격적인 로깅 서비스를 인스턴스화하지 않으려는

[Export("/MyViewModel")] 
public class MyViewModel 
{ 
    [ImportingConstructor] 
    public MyViewModel(
     [Import("/Services/LoggingService")] ILoggingService l) 
    { 
     logger = l; 
    } 

    private ILoggingService logger { get; set; } 

    /* ... */ 
} 

을, 그래서 나는 ILoggingService를 구현하는 MockLoggingService 클래스를 가지고 있고, 모든 로그 메시지를 삼킨다. (또는 당신이 신경 쓰면 적절한 메시지가 생성되는지 검사한다.) 그런 다음 단위 테스트에서이 작업을 수행 할 수 있습니다.

MyViewModel target = new MyViewModel(new MockLoggingService());