MEF2 轻量级 System.Composition 带元数据
MEF2 Lightweight System.Composition with Metadata
完全缺乏如何使用轻量级 MEF2 的示例,System.Composition,这使得这很棘手。我只使用 System.Composition
( 而不是 System.ComponentModel.Composition
)。
我想导入具有元数据的部件。我正在使用属性代码。不幸的是,当我尝试获取导出时,我得到了一个很大的空值。
MetadataAttribute
:
namespace Test.ConfigurationReaders
{
using System;
using System.Composition;
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ExportReaderAttribute : ExportAttribute
{
public string Reader { get; set; }
}
}
Export
:
namespace Test.ConfigurationReaders
{
using System.Collections.Generic;
using System.Configuration;
[ExportReader(Reader = "CONFIG")]
public class ConfigReader : IConfigurationReader
{
public IEnumerable<Feature> ReadAll()
{
return new List<Feature>();
}
}
}
ImportMany
并过滤元数据:
namespace Test.Core
{
using System;
using System.Collections.Generic;
using System.Composition;
using System.Composition.Hosting;
using System.Configuration;
using System.Linq;
using System.Reflection;
using ConfigurationReaders;
public sealed class Test
{
static Test()
{
new Test();
}
private Test()
{
SetImports();
Reader = SetReader();
}
[ImportMany]
private static IEnumerable<ExportFactory<IConfigurationReader, ExportReaderAttribute>> Readers { get; set; }
public static IConfigurationReader Reader { get; private set; }
private static IConfigurationReader SetReader()
{
// set the configuation reader based on an AppSetting.
var source =
ConfigurationManager.AppSettings["Source"]
?? "CONFIG";
var readers = Readers.ToList();
var reader =
Readers.ToList()
.Find(
f =>
f.Metadata.Reader.Equals(
source,
StringComparison.OrdinalIgnoreCase))
.CreateExport()
.Value;
return reader;
}
private void SetImports()
{
var configuration =
new ContainerConfiguration().WithAssemblies(
new List<Assembly> {
typeof(IConfigurationReader).Assembly });
var container = configuration.CreateContainer();
container.SatisfyImports(this);
Readers = container.GetExports<ExportFactory<IConfigurationReader, ExportReaderAttribute>>();
}
}
}
不幸的是,Readers
为空。这是此处的示例代码,但我可以看到在我的实际代码中没有元数据的部分,因此至少可以正常工作。
我应该怎么做才能填充 Readers
?
我正在尝试以 .NET Standard 2.0 为目标并从 .NET Core 使用它。
解决方法是更改导出的属性 class:
[Export(typeof(IConfigurationReader))]
[ExportMetadata("Reader", "CONFIG")]
public class ConfigReader : IConfigurationReader
{
}
完全缺乏如何使用轻量级 MEF2 的示例,System.Composition,这使得这很棘手。我只使用 System.Composition
( 而不是 System.ComponentModel.Composition
)。
我想导入具有元数据的部件。我正在使用属性代码。不幸的是,当我尝试获取导出时,我得到了一个很大的空值。
MetadataAttribute
:
namespace Test.ConfigurationReaders
{
using System;
using System.Composition;
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ExportReaderAttribute : ExportAttribute
{
public string Reader { get; set; }
}
}
Export
:
namespace Test.ConfigurationReaders
{
using System.Collections.Generic;
using System.Configuration;
[ExportReader(Reader = "CONFIG")]
public class ConfigReader : IConfigurationReader
{
public IEnumerable<Feature> ReadAll()
{
return new List<Feature>();
}
}
}
ImportMany
并过滤元数据:
namespace Test.Core
{
using System;
using System.Collections.Generic;
using System.Composition;
using System.Composition.Hosting;
using System.Configuration;
using System.Linq;
using System.Reflection;
using ConfigurationReaders;
public sealed class Test
{
static Test()
{
new Test();
}
private Test()
{
SetImports();
Reader = SetReader();
}
[ImportMany]
private static IEnumerable<ExportFactory<IConfigurationReader, ExportReaderAttribute>> Readers { get; set; }
public static IConfigurationReader Reader { get; private set; }
private static IConfigurationReader SetReader()
{
// set the configuation reader based on an AppSetting.
var source =
ConfigurationManager.AppSettings["Source"]
?? "CONFIG";
var readers = Readers.ToList();
var reader =
Readers.ToList()
.Find(
f =>
f.Metadata.Reader.Equals(
source,
StringComparison.OrdinalIgnoreCase))
.CreateExport()
.Value;
return reader;
}
private void SetImports()
{
var configuration =
new ContainerConfiguration().WithAssemblies(
new List<Assembly> {
typeof(IConfigurationReader).Assembly });
var container = configuration.CreateContainer();
container.SatisfyImports(this);
Readers = container.GetExports<ExportFactory<IConfigurationReader, ExportReaderAttribute>>();
}
}
}
不幸的是,Readers
为空。这是此处的示例代码,但我可以看到在我的实际代码中没有元数据的部分,因此至少可以正常工作。
我应该怎么做才能填充 Readers
?
我正在尝试以 .NET Standard 2.0 为目标并从 .NET Core 使用它。
解决方法是更改导出的属性 class:
[Export(typeof(IConfigurationReader))]
[ExportMetadata("Reader", "CONFIG")]
public class ConfigReader : IConfigurationReader
{
}