MEF
Managed Extensibility Framework(MEF
)是一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI
)等。
Fireasy 提供了对 MEF
的封装,位于 Fireasy.Common.Composition
命名空间下。
1、使用 Imports 静态类
使用 Imports
静态类的 GetServiceIServiceProvider
一样获取相关的实例。它的映射依赖于 ExportAttribute
特性。如下所示:
public interface IService
{
}
[Export(typeof(IService))]
public class ServiceImpl : IService
{
}
[TestMethod]
public void TestGetService()
{
var obj = Imports.GetService<IService>();
Assert.IsNotNull(obj);
}
如果定义了多个实现类的话,可以使用 GetServices
[Export(typeof(IService))]
public class ServiceImpl1 : IService
{
}
[Export(typeof(IService))]
public class ServiceImpl2 : IService
{
}
[TestMethod]
public void TestGetServices()
{
var count = Imports.GetServices<IService>().Count();
Assert.AreEqual(2, count);
}
ExportAttribute
特性可以指定一个契约名称,Imports
类也可以根据契约名称获取相应的实例。如下所示:
[Export("One", typeof(IService))]
public class ServiceImpl1 : IService
{
}
[Export("Tow", typeof(IService))]
public class ServiceImpl2 : IService
{
}
[TestMethod]
public void TestGetServices()
{
var obj = Imports.GetService<IService>("Tow");
Assert.IsTrue(obj is ServiceImpl2);
}
2、部件目录
默认的部件目录使用的是 AssemblyDirectoryCatalog
类,即在当应用程序目录下遍列所有程序集(*.dll),你可以设置 Container 属性来改变部件目录。如下所示:
[Export(typeof(IService))]
public class ServiceImpl1 : IService
{
}
[Export(typeof(IService))]
public class ServiceImpl2 : IService
{
}
[TestMethod]
public void TestSingleService()
{
//使用 SingleCompositionContainer 后,只会从多个部件中导出一个实例
Imports.Container = new CompositionContainer(new SingleCompositionContainer());
var count = Imports.GetServices<IService>().Count();
Assert.AreEqual(1, count);
}
使用 ConventionalCatalog
类像 Container
一样手动添加接口与实现的映射;使用 FilterCompositionContainer
类指定导出的过滤函数。
3、配置
使用配置,可以缩放部件目录所遍列的文件数量,提高程序的效率。使用配置后,部件目录对应的是 ConfigurationCatalog
类,它是基于以下的配置文件:
- .Net Framework 下的 app.config 或 web.config 文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="fireasy">
<section name="imports" type="Fireasy.Common.Composition.Configuration.ImportConfigurationSectionHandler, Fireasy.Common"/>
</sectionGroup>
</configSections>
<fireasy>
<imports>
<import name="demo" assembly="demo" />
<import name="import" importType="demo.IService, demo" />
</imports>
</fireasy>
</configuration>
- .Net Core 下的 appsettings.json 文件
{
"fireasy": {
"imports": {
"settings": {
"demo": {
"assembly": "demo"
},
"import": {
"importType": "demo.IService, demo"
}
}
}
}
}