C# 从Silverlight中的Castle内核导入MEF

C# 从Silverlight中的Castle内核导入MEF,c#,silverlight,silverlight-4.0,mef,castle,C#,Silverlight,Silverlight 4.0,Mef,Castle,我目前在我的项目中使用MEF,但是,一个遗留组件使用Castle导出其所有组件 我希望在创建新对象时,除了从Xap获得导出外,还能够从这个内核导入 这可能吗?您能给我看一些示例代码吗?MEF的设计尽可能灵活,它的一个秘密隐藏但真正不错的功能是能够定义新的ExportProvider实例,允许您插入其他组件。我之前在ASP.NET MVC with MEF项目中使用了公共服务定位器项目(参见第3部分),讨论了这一点 CSL是一种非常灵活的方法,因为对于许多现有的IoC容器,如Castle、Auto

我目前在我的项目中使用MEF,但是,一个遗留组件使用Castle导出其所有组件

我希望在创建新对象时,除了从Xap获得导出外,还能够从这个内核导入


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

MEF的设计尽可能灵活,它的一个秘密隐藏但真正不错的功能是能够定义新的
ExportProvider
实例,允许您插入其他组件。我之前在ASP.NET MVC with MEF项目中使用了公共服务定位器项目(参见第3部分),讨论了这一点

CSL是一种非常灵活的方法,因为对于许多现有的IoC容器,如Castle、Autofac、Ninject、Unity等,都有许多特定的CSL实现


我们可以找到另一个很好的例子,它展示了一种稍有不同但基本相似的方法。

正如Matthew正确地说的,实现这一点的方法是使用
导出提供者

另一个例子是(它演示了从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; }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.ComponentModel.Composition;
使用System.ComponentModel.Composition.Hosting;
使用System.ComponentModel.Composition.Primitives;
使用System.Linq;
使用Castle.MicroKernel;
使用Castle.MicroKernel.Registration;
使用温莎城堡;
命名空间MEFCastleBridge
{
公共类CastleExportProvider:ExportProvider
{
温莎集装箱;
专用只读词典导出=
新字典();
私有只读对象_sync=新对象();
公共CastleExportProvider(WindsorContainer容器)
{
_容器=容器;
var handlers=_container.Kernel.GetAssignableHandlers(typeof(object));
foreach(处理程序中的变量处理程序)
{
RegisterCastleComponent(处理程序);
}
_container.Kernel.ComponentRegistered+=ComponentRegistered;
}
受保护的覆盖IEnumerable GetExportsCore(
导入定义,原子组合(原子组合)
{
var contractDefinition=定义为ContractBasedImportDefinition;
var retVal=Enumerable.Empty();
if(contractDefinition!=null)
{
字符串contractName=contractDefinition.contractName;
如果(!string.IsNullOrEmpty(contractName))
{
var导出=
从e in_导出
其中string.Compare(e.Key.ContractName、ContractName、StringComparison.OrdinalIgnoreCase)==0
选择e值;
如果(exports.Count()>0)
{
retVal=exports.First();
}
}
}
返回返回;
}
无效注册表CastleComponent(IHandler处理程序)
{
var type=handler.Service;
var contractName=type.ToString();
锁定(同步)
{
var found=来自e in_导出
其中string.Compare(e.Key.ContractName,
contractName,StringComparison.OrdinalIgnoreCase)==0
选择e;
if(find.Count()==0)
{
var metadata=newdictionary();
var定义=新的导出定义(合同名称、元数据);
_exports.Add(定义,newlist());
}
var wrapper=新导出(contractName,()=>\u container.Resolve(type));
找到.First().Value.Add(包装器);
}
}
无效组件已注册(字符串键,IHandler处理程序)
{
RegisterCastleComponent(处理程序);
}
}
公共接口IMY组件
{
字符串字符串{get;}
}
公共类注册组件:IMyComponent
{
公共字符串字符串{get{return“RegisteredComponent”;}
}
[导出(类型(IMY组件))]
公共类导出组件:IMyComponent
{
公共字符串字符串{get{return“ExportedComponent”;}
}
公共类导出示例
{
//将包含RegisteredComponent和ExportedComponent的实例
[进口数量]
公共列表组件{get;set;}
公共导出示例()
{
//创建Windsor容器并添加类型。
var container=新的WindsorContainer();
container.Register(Component.For().ImplementedBy().lifety.Singleton);
//除了DeploymentCatalog之外,还添加导出提供程序
var compContainer=new CompositionContainer(new DeploymentCatalog(),new CastleExportProvider(container));
//在尝试满足导入之前,只应调用一次。
CompositionHost.Initialize(compContainer);
CompositionInitializer.SatisfyImports(此);
Test=string.Join(“,”,Components.Select(c=>c.DoSomething));
}
公共字符串测试{get;set;}
}
}