MEF可以用来获取标记为[Export]的类的System.Type吗?

发布于 2024-09-13 18:12:57 字数 243 浏览 4 评论 0原文

我已成功使用 MEF 获取导出的类实例。但是,我遇到了一种情况,我需要枚举一组导出的派生类而不实例化它们。我查阅了 CompositionContainer 的文档,它似乎只能返回对象实例。

我知道我可以在每个派生类中拥有一个静态 Type 字段并将其导出,或者进行自己的反射,但我想知道是否有一种内置方法可以使用 [Export] 属性,然后枚举它们的 System.Type

I've been successfully using MEF to obtain exported class instances. However, I came across a situation where I need to enumerate a set of exported derived classes without instantiating them. I've looked up CompositionContainer's documentation and it only seems to be able to return object instances.

I know I could have a static Type field in each derived class and export it, or do my own reflection, but I'd like to know if there's a build-in way to mark classes with the [Export] attribute and then enumerate their System.Type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

末が日狂欢 2024-09-20 18:12:57

正如leppie 所说,没有内置方法可以做到这一点。这是设计使然。导出和类型之间不一定存在一对一的映射(例如,任意数量的部分都可以具有 String 类型的属性导出)。此外,对于不同的编程模型,该部分可能来自配置文件或动态编程语言,因此尝试获取与其关联的 CLR 类型可能没有多大意义。

As leppie said, there's no built in way to do this. This is by design. There's not necessarily a one-to-one mapping between exports and types (any number of parts could have property exports of type String, for example). Also, with different programming models, the part may have come from a configuration file or a dynamic programming language, so trying to get the CLR type associated with it might not make much sense.

甜点 2024-09-20 18:12:57

根据您尝试执行的操作范围,您还可以使用 System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices,这些 API 是为了支持默认目录的缓存而引入的。假设您正在使用标准属性编程模型,并且您知道所有的 [Export] 都处于类型级别(即它们不在成员上),那么您可以对目录中的每个部件调用 GetPartType(part) 来获取类型。

正如 Daniel 指出的,如果您使用其他编程模型,那么这对您不起作用,但如果您仅使用 MEF 附带的默认目录,那么它应该可以完成这项工作。

Depending on the scope of what you are trying to do you could potentially also use System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices which were API's introduced to support caching of the default catalogs. Assuming you are using the standard attributed programming model and you know all your [Export]'s are at the type level (i.e. they aren't on members) then you can call GetPartType(part) on each part in your catalog to get the type.

As Daniel pointed out if you are using other programming models then this will not work for you but if you are using only the default catalogs that come with MEF then it should do the job.

十六岁半 2024-09-20 18:12:57

这不是您要找的吗?

    public static IEnumerable<Type> GetExportedTypes<T>()
    {
        return catalog.Parts
            .Where(part => IsPartOfType(part, typeof(T).FullName))
            .Select(part => ReflectionModelServices.GetPartType(part).Value);
    }

    private static bool IsPartOfType(ComposablePartDefinition part, string exportTypeIdentity)
    {
        return (part.ExportDefinitions.Any(
            def => def.Metadata.ContainsKey("ExportTypeIdentity") &&
                   def.Metadata["ExportTypeIdentity"].Equals(exportTypeIdentity)));
    }

Isn't this what you're looking for ?

    public static IEnumerable<Type> GetExportedTypes<T>()
    {
        return catalog.Parts
            .Where(part => IsPartOfType(part, typeof(T).FullName))
            .Select(part => ReflectionModelServices.GetPartType(part).Value);
    }

    private static bool IsPartOfType(ComposablePartDefinition part, string exportTypeIdentity)
    {
        return (part.ExportDefinitions.Any(
            def => def.Metadata.ContainsKey("ExportTypeIdentity") &&
                   def.Metadata["ExportTypeIdentity"].Equals(exportTypeIdentity)));
    }
戒ㄋ 2024-09-20 18:12:57

为此使用反射有什么问题吗?

如果不是,那就是我的答案:)

编辑:

没有内置方法可以获取具有特定属性的程序集中的所有类型。

Is there anything wrong with using Reflection for this?

If no, that's my answer :)

Edit:

There is no builtin way to get all the types in an assembly with a certain attribute.

む无字情书 2024-09-20 18:12:57

通常,您实际上并不需要根据类型选择导出。相反,您可以根据元数据找到“正确”的导出。

查看有关 导出和元数据< 的 MEF 编程指南部分/a>.

Typically you don't really need to select an export based on type. Instead, you can find the "correct" export based on metadata.

Have a look at the MEF programming guide section on Exports and metadata.

罗罗贝儿 2024-09-20 18:12:57

这可能有点旧,但我相信在这里发布正确的回复是件好事,因为这个问题在 Google 搜索中排在第一位:

是的,你可以做到这一点,感谢 Ricci Gian Maria

http://www .codewrecks.com/blog/index.php/2012/05/08/getting-the-list-of-type-linked-to-a-given-export-in-mef/

This might be a bit old but I believe its good to post the correct response in here because the question comes first in Google search:

Yes you can do this thanks to Ricci Gian Maria

http://www.codewrecks.com/blog/index.php/2012/05/08/getting-the-list-of-type-associated-to-a-given-export-in-mef/

偏爱自由 2024-09-20 18:12:57

您可以将导出属性视为自定义属性。我还没有测试装配体非常大时的性能。

 Type[] GetType(Assembly assembly)
 {
     return assembly.GetTypes().Where(type => Attribute.GetCustomAttribute(type, typeof(ExportAttribute)).Length > 0).ToArray();
 }

You can treat the Export attribute as a custom attribute. I haven't test the performance when the assembly is very large.

 Type[] GetType(Assembly assembly)
 {
     return assembly.GetTypes().Where(type => Attribute.GetCustomAttribute(type, typeof(ExportAttribute)).Length > 0).ToArray();
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文