2011-05-04 4 views
3

원본 소스 코드MEF 재산권에 allways 돌아 널

내 BusinessObjects.dll 파일에 간단한 비즈니스 오브젝트가있어 :

내 SharedUI.dll에서
namespace BusinessObjects 
{ 
    public class MyClass 
    { 
     public MyClass() 
     { 
      DateTime = DateTime.Now; 
     } 

     public DateTime DateTime { get; set; } 
    } 
} 

나는이있어 " 내가 현재 선택된 MyClass에에 referece 유지하기 위해 사용하는 상황에 제공 "클래스, - 이것은 simplyfied 예입니다 기억을 :) ...

namespace SharedUI 
{ 
    public class AppContext 
    { 
     [Export] 
     public MyClass SelectedMyClass { get; private set; } 

     public void SetupContext(MyClass myClass) 
     { 
      SelectedMyClass = myClass; 
     } 

     public static AppContext Context 
     { 
      get 
      { 
       if (context == null) 
       { 
        context = new AppContext(); 
       } 
       return context; 
      } 
     } 

     private static AppContext context; 
    } 
} 

내 MefTe st.exe이 클래스가 있습니다

namespace MefTest 
{ 
    public class Program 
    { 
     [Import] 
     public MyClass MyClass { get; set; } 

     private void Compose() 
     { 
      var ventSystem = new MyClass(); 
      AppContext.Context.SetupContext(ventSystem); 

      var executingAssembly = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 
      var contextAssembly = new AssemblyCatalog(Assembly.LoadFile(string.Format(@"{0}\SharedUI.dll", Environment.CurrentDirectory))); 
      var catalog = new AggregateCatalog(executingAssembly, contextAssembly); 

      var container = new CompositionContainer(catalog); 

      container.ComposeParts(this); 
     } 

     private void Run() 
     { 
      Compose(); 

      // MyClass is always null in the next line? 
      Console.WriteLine(MyClass.DateTime.ToString()); 

      Console.ReadKey(); 
     } 

     private static void Main(string[] args) 
     { 
      var p = new Program(); 
      p.Run(); 
     } 
    } 
} 

내가 너무 나를 참아주세요 :) MEF 신인이야을

다니엘 Plaisted

MyClass의 소스로부터 제안을 소스 코드와 동일하다 업데이트] ...

SharedUI.dll 이제 다음과 같습니다

namespace SharedUI 
{ 
    [Export] 
    public class AppContext 
    { 
     [Export(typeof(MyClass))] 
     public MyClass SelectedMyClass { get; private set; } 

     public void SetupContext(MyClass myClass) 
     { 
      SelectedMyClass = myClass; 
     } 
    } 
} 

MefTest.exe 이제 다음과 같습니다 : 나는 작업을 얻을 수 없기 때문에

namespace MefTest 
{ 
    public class Program 
    { 
     [Import] 
     public MyClass MyClass { get; set; } 

     [Import] 
     public AppContext AppContext { get; set; } 

     private void Compose() 
     { 
      var executingAssembly = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 
      var contextAssembly = new AssemblyCatalog(Assembly.LoadFile(string.Format(@"{0}\SharedUI.dll", Environment.CurrentDirectory))); 
      var catalog = new AggregateCatalog(executingAssembly, contextAssembly); 

      var container = new CompositionContainer(catalog); 

      container.ComposeParts(this); 

      var myClass = new MyClass(); 
      AppContext.SetupContext(myClass); 
     } 

     private void Run() 
     { 
      Compose(); 

      // AppContext.SelectedMyClass is NOT null in the next line... which is good I guess :) 
      Console.WriteLine(AppContext.SelectedMyClass.DateTime.ToString()); 

      // MyClass is always null in the next line? 
      Console.WriteLine(MyClass.DateTime.ToString()); 

      Console.ReadKey(); 
     } 

     private static void Main(string[] args) 
     { 
      var p = new Program(); 
      p.Run(); 
     } 
    } 
} 

내가 무슨 일을하고 있는가?

+0

AssemblyCatalog에 'GUI'가로드되었는지 확인 했습니까? –

+0

@Jonas : "GUI"란 무엇입니까? 프로그램 클래스 인 AppContext-clas가 포함되어 있습니까? s 또는 MyClass- 클래스 ...? – kennethkryger

+0

죄송합니다. 두 가지 다른 질문이 생깁니다. AppContext 클래스입니다. 그것이 MEF에 의해로드되고 있는지 확인 했습니까? –

답변

2

, 그것은 만듭니다 클래스의 인스턴스를 호출하고 getter 속성을 호출합니다. 그래서 MEF는 정적 AppContext.Context 인스턴스와 다른 AppContext의 새 인스턴스를 만듭니다 .MEF 인스턴스에 SelectedMyClass 속성이 설정되어 있지 않습니다. 가져 오기가 null이 됨

+0

나는 당신의 제안으로 원래의 질문을 업데이트했습니다 - 그러나 나는 그것을 얻을 수 없습니까? 내가 여기서 무엇을 놓치고 있니? – kennethkryger

+2

@kenneth 수정 된 샘플에는 다른 문제점이 있습니다. MEF는 한 번만 내보내기 값을 가져오고 나중에 변경되는지 여부를 알 수 없습니다. ComposeParts (this)를 호출하면 MyClass 내보내기 값을 가져옵니다. 나중에 해당 특성을 수정하면 내보내기 값에 영향을주지 않습니다. –

0

Export 특성을 잘못된 위치에 넣었습니다. 이 클래스의 인스턴스를 원하는 목적지 속성 [가져 오기]를 사용하여 다음

namespace BusinessObjects 
{ 
[Export] 
public class MyClass 
{ 
    public MyClass() 
    { 
     DateTime = DateTime.Now; 
    } 

    public DateTime DateTime { get; set; } 
} 
} 

을 그리고 :

당신과 같이 MyClass의 정의에 넣어해야합니다.

비고 : 당신은 클래스의 특정 인스턴스를 이동하는 MEF를 사용할 수 없습니다 (이 마음에 들지). MEF는 요청 된 유형의 인스턴스를 만들고 표시된 위치에 삽입하는 데 사용됩니다.

MEF에 대한 자세한 내용은 프로젝트 페이지 CodePlex을 확인하십시오.

+0

설명서 (영문) [링크] (http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.exportattribute.aspx)를 읽으면 Export 특성을 클래스, methods, propertis 및 fields ... 특히 Remarks 섹션의 다음 인용문에 관심이 있습니다 : "ExportAttribute는 전체 클래스 또는 클래스의 속성, 필드 또는 메서드를 꾸밀 수 있습니다. 전체 클래스가 장식되어 있으면 클래스의 인스턴스가 내 보낸 객체입니다. ** 클래스의 멤버가 장식 된 경우 내 보낸 객체는 데코레이션 된 멤버의 값이됩니다. ** " – kennethkryger

+1

[Export (typeof (MyClass)] public MyClass SelectedMyClass {get ; 개인 집합;} – maartenba

+0

@maartenba : 불행히도 그걸 고치는 것 같지 않습니다. ( – kennethkryger

1

문제는 :

[Import]  public MyClass MyClass { get; set; } 

더 [내보내기] MyClass에 대해 정의 된 s는 없습니다.

내가 발견 ... MEF는 "알고"물건에 따라이 appplication을 구성하며, 이후는 "MyClass에"를 모르는이 하나

[Export]  public MyClass SelectedMyClass { get; private set; } 

이것은 당신이에 MEF를 속이려는 것을 의미합니다 때때로 부품 중 하나를 업데이트합니까? 이에 대한 해결책은 "런타임"개체를 포함하는 사용자 지정 카탈로그를 만드는 것입니다.이 개체는 언제든지 MyClass에 대해 내 보낸 값을 업데이트 할 수 있습니다. 현재의 구현은 결코 MyClass를 해결하지 않을 것입니다 ...

[편집 됨 : ] 회원도 장식 할 수 있지만 클래스 유형을 추가해야합니다. 그래서이 작동합니다 :

이 에게

은 [내보내기 (대해서 typeof (MyClass에)] 공공 MyClass에 SelectedMyClass {얻을; 개인 설정을} MEF는 클래스의 속성에있는 내보내기를 얻을 필요가있는 경우

+0

불행히도 그걸 고치는 것 같지 않습니다. ( – kennethkryger