4

まずは素朴な疑問。

eventMEF (System.ComponentModel.Composition) がパーツのインスタンスを作成するときに を受け取ることはできますか? これが発生した場合、作成されたオブジェクトを反映して、さまざまな属性を関連付けたいと考えています。Spring.Net では、これはIObjectPostProcessorインターフェースで可能です。

背景は、MEF でパブリッシャー/サブスクライバー パターンを実装しようとしているということです。基本的に、サブスクライバー クラスはこれを行います。

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

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

そして、いつ MyController がインスタンス化されたかを検出CommandAttribute.

メニュー項目などのパブリッシャーはCommand.Get("Print").Fire()、前述のイベントをパブリッシュします。

2 番目の質問

MEF には、私が見逃している別のパターンがあるかもしれません!!!

MEF、Prism、および 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;
  }

}

4

2 に答える 2

3

これは役に立たないかもしれませんが、部品自体は完全に構成されたときに通知を受け取ることができます:

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();
  }

}
于 2012-06-18T17:59:57.603 に答える
1

MEF Contrib(コードプレックス上のMEF Contrib、またはnuGetでインストールできます)からInterceptingCatalogを使用し、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);
于 2012-07-01T07:58:22.547 に答える