Dav*_*ita 5 c# dependency-injection mef
我想在我的项目中使用MEF作为DI.我有一个项目,每个应该编写的类都驻留在那里(它们共享一个接口).现在我想通过指定元数据值来创建其中一个.这是定义:
public interface IGatewayResponseReader
{
object Read(string msg);
}
[Export(typeof(IGatewayResponseReader))]
[ExportMetadata(G3Reader.META_KEY, "value1")]
public class TestReader1 : IGatewayResponseReader
{
...
}
[Export(typeof(IGatewayResponseReader))]
[ExportMetadata(G3Reader.META_KEY, "value2")]
public class TestReader2 : IGatewayResponseReader
{
...
}
Run Code Online (Sandbox Code Playgroud)
现在我想通过MEF创建一个TestReader1实例,但我不知道如何通过CompositionContainer按元数据进行过滤.我想要类似的东西
Container.GetExportedValue<IGatewayResponseReader>();
Run Code Online (Sandbox Code Playgroud)
但要指定元数据以选择要创建的类实例.
非常感谢您的帮助.
谢谢.
@Dmitry Ornatsky提供的答案是正确的,但提供导出元数据的首选方法是使用自定义导出属性使用强类型元数据:
public interface IGatewayResponseReaderMetadata
{
string Key { get; }
}
[MetadataAttribute]
[AttributeUsage( AttributeTargets.Class | AttributeTargets.Property )]
public class GatewayResponseReaderExportAttribute : ExportAttribute
{
public GatewayResponseReaderExportAttribute( string key )
: base( typeof( IGatewayResponseReader ) )
{
this.Key = key;
}
public string Key { get; set; }
}
[GatewayResponseReaderExport("value1")]
public class TestReader1 : IGatewayResponseReader
{
}
Run Code Online (Sandbox Code Playgroud)
然后,可以将用于查找导入的代码设置为类型安全的.请注意,在访问Value属性之前检查导入是否为null是个好主意:
class Program
{
[ImportMany]
private List<Lazy<IGatewayResponseReader, IGatewayResponseReaderMetadata>> _readers;
static void Main( string[] args )
{
CompositionContainer container = new CompositionContainer( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );
Program program = new Program();
container.SatisfyImportsOnce( program );
var reader = program._readers.FirstOrDefault( r => r.Metadata.Key == "value1" );
if ( reader != null )
reader.Value.Read( ... );
}
}
Run Code Online (Sandbox Code Playgroud)