2012-06-18 29 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的贴子,但看起来相当复杂。

FYI

仅供参考,以下是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

您可以使用InterceptingCatalog从MEF的Contrib(MEF Contrib on codeplex,或者您可以通过的NuGet安装),并实现IExportedValueInterceptor接口线了有CommandAttribute方法:

//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目录,你需要添加拦截配置与拦截器(CommandAttributeProcessor)和包装你的目录下InterceptingCatalog这样的:

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

此外,您可能已经知道这一点(它可能并不真正与您正在尝试做什么有关),但是您可以修饰您的导出和导入,例如具体的实现被命名。所以,你可以有一个出口类是这样的:

[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。但是,我的用户类(控制器)只是打印而已。我需要一些模式来允许调用多个**订阅者方法。 –