【问题标题】:MEF Import from a Castle Kernel in Silverlight从 Silverlight 中的 Castle Kernel 导入 MEF
【发布时间】:2023-03-19 12:25:02
【问题描述】:

我目前在我的项目中使用 MEF,但是,旧组件使用 Castle 导出其所有组件。

除了从 Xap 获取导出之外,我还希望能够在创建新对象时从该内核导入。

这可能吗?你能给我一些示例代码吗?

【问题讨论】:

    标签: c# silverlight silverlight-4.0 mef castle


    【解决方案1】:

    MEF 被设计为尽可能灵活,其秘密隐藏但真正好的功能之一是能够定义新的ExportProvider 实例,允许您插入其他组件。我之前已经通过在带有 MEF 项目的 ASP.NET MVC 中使用 Common Service Locator 项目来讨论过这个问题(参见第 3 部分 here)。

    CSL 是一种很好的灵活方法,因为许多现有的 IoC 容器都有许多特定的 CSL 实现,例如 Castle、Autofac、Ninject、Unity 等。

    另一个很好的例子是here,它展示了一种略有不同但基本相似的方法。

    【讨论】:

      【解决方案2】:

      正如马修所说的那样,这样做的方法是使用ExportProvider

      另一个例子是here(它演示了从 Xaml 导出)。 以下是我最终解决问题的方法。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-03
        相关资源
        最近更新 更多