2011-07-29 6 views
2

私は現在MEFをプロジェクトで使用していますが、従来のコンポーネントはすべてのコンポーネントをエクスポートするためにCastleを使用しています。Silverlightで城のカーネルからMEFをインポート

新しいオブジェクトを作成するときに、このカーネルからインポートすることができます。また、Xapからのエクスポートを取得することもできます。

これは可能ですか?いくつかのサンプルコードを表示できますか?

答えて

1

マシューが正しく言ったように、これはExportProvider

別の例を使用している実行する方法は、(それがXAMLからの輸出を実証)hereです。 以下は、私が最後に問題を解決するために行ったことです。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.ComponentModel.Composition; 
using System.ComponentModel.Composition.Hosting; 
using System.ComponentModel.Composition.Primitives; 
using System.Linq; 
using Castle.MicroKernel; 
using Castle.MicroKernel.Registration; 
using Castle.Windsor; 

namespace MEFCastleBridge 
{ 
    public class CastleExportProvider : ExportProvider 
    { 
     WindsorContainer _container; 
     private readonly Dictionary<ExportDefinition, List<Export>> _exports = 
      new Dictionary<ExportDefinition, List<Export>>(); 
     private readonly object _sync = new object(); 

     public CastleExportProvider(WindsorContainer container) 
     { 
      _container = container; 
      var handlers = _container.Kernel.GetAssignableHandlers(typeof(object)); 
      foreach (var handler in handlers) 
      { 
       RegisterCastleComponent(handler); 
      } 
      _container.Kernel.ComponentRegistered += ComponentRegistered; 
     } 

     protected override IEnumerable<Export> GetExportsCore(
      ImportDefinition definition, AtomicComposition atomicComposition) 
     { 
      var contractDefinition = definition as ContractBasedImportDefinition; 
      var retVal = Enumerable.Empty<Export>(); 
      if (contractDefinition != null) 
      { 
       string contractName = contractDefinition.ContractName; 
       if (!string.IsNullOrEmpty(contractName)) 
       { 
        var exports = 
         from e in _exports 
         where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0 
         select e.Value; 

        if (exports.Count() > 0) 
        { 
         retVal = exports.First(); 
        } 
       } 
      } 

      return retVal; 
     } 

     void RegisterCastleComponent(IHandler handler) 
     { 
      var type = handler.Service; 
      var contractName = type.ToString(); 
      lock (_sync) 
      { 
       var found = from e in _exports 
          where string.Compare(e.Key.ContractName, 
           contractName, StringComparison.OrdinalIgnoreCase) == 0 
          select e; 

       if (found.Count() == 0) 
       { 
        var metadata = new Dictionary<string, object>(); 
        var definition = new ExportDefinition(contractName, metadata); 
        _exports.Add(definition, new List<Export>()); 
       } 

       var wrapper = new Export(contractName,() => _container.Resolve(type)); 
       found.First().Value.Add(wrapper); 
      } 
     } 

     void ComponentRegistered(string key, IHandler handler) 
     { 
      RegisterCastleComponent(handler); 
     } 
    } 

    public interface IMyComponent 
    { 
     string TheString { get; } 
    } 

    public class RegisteredComponent : IMyComponent 
    { 
     public string TheString { get { return "RegisteredComponent"; } } 
    } 

    [Export(typeof(IMyComponent))] 
    public class ExportedComponent : IMyComponent 
    { 
     public string TheString { get { return "ExportedComponent"; } } 
    } 

    public class ExportExample 
    { 
     // Will contain an instance of RegisteredComponent and ExportedComponent 
     [ImportMany] 
     public List<IMyComponent> Components { get; set; } 

     public ExportExample() 
     { 
      // Create a Windsor container and add a type. 
      var container = new WindsorContainer(); 
      container.Register(Component.For<IMyComponent>().ImplementedBy<MyComponent>().LifeStyle.Singleton); 

      // Add the Export Provider, in addition to the DeploymentCatalog 
      var compContainer = new CompositionContainer(new DeploymentCatalog(), new CastleExportProvider(container)); 
      // Should only be called once, before any attempt to SatisfyImports. 
      CompositionHost.Initialize(compContainer); 
      CompositionInitializer.SatisfyImports(this); 

      Test = string.Join(", ", Components.Select(c => c.DoSomething)); 
     } 

     public string Test { get; set; } 
    } 
} 
2

MEFはできるだけ柔軟に設計されていますが、秘密裏に隠されていて本当に素敵な機能の1つは、新しいコンポーネントをプラグインできる新しいExportProviderインスタンスを定義する機能です。私はこれまで、MEFプロジェクトのASP.NET MVC(パート3 hereを参照)でCommon Service Locatorプロジェクトを利用してこれについて説明しました。

CSLは、等

別の好例城、Autofac、Ninject、ユニティなどの既存のIoCコンテナの多くのために多くの特定のCSL実装が存在するようhereを見つけることができる、素敵な柔軟なアプローチでありますわずかに異なるが基本的には同様のアプローチを示す。

関連する問題