C# 从Silverlight中的Castle内核导入MEF
我目前在我的项目中使用MEF,但是,一个遗留组件使用Castle导出其所有组件 我希望在创建新对象时,除了从Xap获得导出外,还能够从这个内核导入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的设计尽可能灵活,它的一个秘密隐藏但真正不错的功能是能够定义新的
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;}
}
}