2012-06-18 5 views
4

첫째, 간단한 질문입니다.수출 파트의 MEF 인스턴스화

MEF (System.ComponentModel.Composition)가 파트의 인스턴스를 만들 때 event을받을 수 있습니까? 이 때 나는 생성 된 객체를 반사시키고 다양한 속성을 연결하려고합니다. Spring.Net에서 이것은 IObjectPostProcessor 인터페이스로 가능합니다.

배경은 MEF에서 Publisher/Subscriber 패턴을 구현하려고하는 것입니다.

class MyContoller 
{ 
    [Command("Print")] 
    public void Print() { ... } 

    [Command("PrintPreview")] 
    public void PrintPreview() { ... } 
} 

그리고 MyController에 인스턴스화하고 CommandAttribute이 선까지 어떤 방법 때 감지 할 : 기본적으로 가입자 클래스는이 작업을 수행합니다.

게시자 (예 : 메뉴 항목)는 앞서 언급 한 이벤트를 게시하기 위해 Command.Get("Print").Fire()을 게시합니다.

두 번째 질문

아마 내가 놓친 거지 MEF에서 다른 패턴이있다!

MEF, Prism and the Event Aggregate에 대한 일부 게시물을 보았지만 상당히 복잡해 보입니다.

은 참고

그냥 참조를 위해, 여기 Spring.Net 구현을위한 원래의 :

class CommandAttributeProcessor : IObjectPostProcessor 
{ 
    static ILog log = LogManager.GetLogger(typeof(CommandAttributeProcessor)); 

    public object PostProcessAfterInitialization(object instance, string objectName) 
    { 
    foreach (MethodInfo methodInfo in instance.GetType().GetMethods()) 
    { 
     foreach (CommandAttribute attr in methodInfo.GetCustomAttributes(typeof(CommandAttribute), true)) 
     { 
      if (log.IsDebugEnabled) 
       log.Debug(String.Format("Binding method '{0}.{1}' to command '{2}'.", instance.GetType().Name, methodInfo.Name, attr.CommandName)); 

      Command command = Command.Get(attr.CommandName); 
      command.Execute += (EventHandler) Delegate.CreateDelegate(typeof(EventHandler), instance, methodInfo); 
     } 
    } 
    return instance; 
    } 

    public object PostProcessBeforeInitialization(object instance, string name) 
    { 
    return instance; 
    } 

}

+0

방금 ​​본 적이 있습니다. http://hammett.castleproject.org/index.php/2009/02/mef-exporting-and-importing-methods/ 아마도 이것이 방법입니다. –

답변

1

당신은 MEF있는 contrib에서 (MEF Contrib on codeplex를하거나 nuGet하여 설치할 수 있습니다) InterceptingCatalog를 사용할 수 있으며 IExportedValueInterceptor에게 인터페이스를 구현 : 그래서, 당신은이 같은 수출 클래스 뭔가를 할 수

//using System.ComponentModel.Composition; 
//using System.ComponentModel.Composition.Hosting; 
//using MefContrib.Hosting.Interception; 
//using MefContrib.Hosting.Interception.Configuration; 

public class CommandAttributeProcessor : IExportedValueInterceptor 
{ 
    public object Intercept(object value) 
    { 
     foreach (MethodInfo methodInfo in value.GetType().GetMethods()) 
     { 
      foreach (CommandAttribute attr in methodInfo.GetCustomAttributes(typeof(CommandAttribute), true)) 
      { 
       // do something with command attribute 
      } 
     } 

     return value; 
    } 
} 

및 MEF 카탈로그를 작성에서 , 당신은 다음과 같이 InterceptingCatalog에 인터셉터 (CommandAttributeProcessor)를 차단 구성을 추가하고 카탈로그를 포장해야합니다

InterceptionConfiguration interceptionConfiguration = new InterceptionConfiguration(); 
interceptionConfiguration.AddInterceptor(new CommandAttributeProcessor()); 
InterceptingCatalog interceptingCatalog = new InterceptingCatalog(assemblyCatalog, interceptionConfiguration); 
CompositionContainer container = new CompositionContainer(interceptingCatalog); 
+0

건배, 내가 찾던 바로 그거야. –

3

이 도움이되지 수 있지만, 일부 자체는 때를 알림을받을 수 있습니다

Automatically call method after part has been composed in MEF

또한 이미 알고있을 것입니다 (실제로는 수행하려는 항목과 관련이 없을 수도 있음). 그러나 구체화 된 구현의 이름이 지정되면 내보내기 및 가져 오기를 꾸밀 수 있습니다. CommandAttribute이 방법을 묶는

[Export("Print", typeof(IPlugin))] 
[PartCreationPolicy(CreationPolicy.Shared)] 
class Print : IPlugin 
{ 
    . 
    . 
    . 
    public Fire() 
    { 
    //Do something; 
    } 
} 


class PrintMenuItem 
{ 
    IPlugin _plugin; 

    [ImportingConstructor] 
    PrintMenuItem([Import("Print", typeof(IPlugin)] plugin) 
    { 
    _plugin = plugin; 
    } 

    void Execute() 
    { 
    _plugin.Fire(); 
    } 

} 
+0

빠른 응답을 주셔서 감사합니다. +1을 받았습니다. 그러나 내 구독자 클래스 (컨트롤러)는 인쇄하는 것보다 훨씬 많은 작업을 수행합니다. ** ** 여러 ** 구독자 메소드를 호출 할 수있는 패턴이 필요합니다. –