gpt4 book ai didi

c# - 实现接口(interface)和匹配属性的 MEF 加载类型

转载 作者:太空狗 更新时间:2023-10-29 20:36:28 25 4
gpt4 key购买 nike

假设我有一个接口(interface) IFileLoader 和属性 FileTypeAttribute

我在 JPEGLoader 中使用 [FileType(".jpg")] 实现了 IFileLoader

我可以使用 MEF 加载实现 IFileLoader 并匹配 .jpg 作为文件扩展名的类 (JPEGLoader),以便我可以实现以下方法:

public void IFileLoader GetLoader(string filename);

这可以用 MEF 完成吗,还是我应该坚持这样做:

var allTypes = assemblies.SelectMany(a => a.GetTypes());
var classes = allTypes.Where(t => t.IsClass && ! t.IsAbstract);
var fileLoaders = classes.where(t => typeof(IFileLoader).IsAssignableFrom(t));
var forType = fileLoaders.Where(t => t.GetAtributeValue<FileTypeAttribute,string>(t => t.FileType, string.Empty) == fileType);
var loaderInstances = fileLoaders.Select(t => Activator.CreateInstance(t) as IFileLoader);

或者至少上面变成了 ILookup,或者我没有考虑过的其他东西?

我希望能够在项目的不同程序集中甚至在插件程序集中实现 IFileLoader。

最佳答案

通过使用 MEF 可以获得您需要的文件加载器和附件Metadata到导出零件。

创建元数据接口(interface)和属性。

public interface IFileTypeMetadata
{
string FileExtension { get; }
}

接口(interface)可以包含您需要的任意数量的属性。对于这个特定问题,它只包含一个属性 FileExtension .重要的是该属性(property)只有 getter . MEF旨在不允许在运行时更改元数据。然后创建保存元数据的属性:

public class FileTypeAttribute : Attribute, IFileTypeMetadata    
{
public string FileExtension { get; set; }
}

FileTypeAttribute类(class)工具IFileTypeMetadata接口(interface),你可以添加一个setterFileExtension属性(property)。需要它来实现 FileLoader类,和 MEF不会提示,因为我们将通过 IFileTypeMetadata 访问元数据接口(interface)包含的属性只有 getters

创建文件加载器类实现的接口(interface)和文件加载器类。

public interface IFileLoader
{
string LoadFile();
}

为了简单起见,该接口(interface)只包含一个方法。这是两个不同的虚拟文件加载器类的示例:

[Export(typeof(IFileLoader))]
[FileType(FileExtension = ".jpg")]
public class JpgFileLoader : IFileLoader
{
public string LoadFile()
{
return "JPG";
}
}

[Export(typeof(IFileLoader))]
[FileType(FileExtension = ".png")]
public class PngFileLoader : IFileLoader
{
public string LoadFile()
{
return "PNG";
}
}

两个类都实现了 IFileLoader接口(interface)并导出为 IFileLoader部分,但它们有不同的元数据,通过 FileType属性。

创建组合容器

var catalog = new DirectoryCatalog("path to directory where dll's are located");
var compositionContainer = new CompositionContainer(catalog);
compositionContainer.ComposeParts();

访问导出的零件

var fileLoaders = compositionContainer.GetExports<IFileLoader, IFileTypeMetadata>();

var jpgFileLoader = fileLoaders.FirstOrDefault(x => x.Metadata.FileExtension == ".jpg");

if (jpgFileLoader != null)
Console.WriteLine(jpgFileLoader.Value.LoadFile()); //should print "JPG"

var pngFileLoader = fileLoaders.FirstOrDefault(x => x.Metadata.FileExtension == ".png");

if (pngFileLoader != null)
Console.WriteLine(pngFileLoader.Value.LoadFile()); //should print "PNG"

关于c# - 实现接口(interface)和匹配属性的 MEF 加载类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23629645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com