如何坚持MEF导入和导出信息到磁盘 [英] How to persist MEF import and export information to disk

查看:153
本文介绍了如何坚持MEF导入和导出信息到磁盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关我的应用程序中的这个问题我想使用MEF扫描可用的插件组件,然后储存所有的序列化格式可以导入和导出信息(例如,一组字符串或内存流)。这是必要的,因为我需要在一个AppDomain边界的转让进出口信息,而无需加载插件组件(主要是我想延迟加载插件)。我发现了一些参考资料,比如这个或的这个但没有一个链接给我任何想法如何:

For my application as described in this question I want to use MEF to scan the available plugin assemblies and then store all the available import and export information in a serialized format (e.g. a set of strings or a memory stream). This is necessary because I need to transfer the import and export information over an AppDomain boundary without loading the plugin assemblies (essentially I want to delay load the plugins). I found some references, for instance this one or this one but none of the links gave me any idea how to:


  • 提取所有的进口和出口从一个程序集

  • 序列化所有所需的导入/导出信息

  • 再后来就重新水合物序列化的信息返回到进口和出口

我想我可以使用的 ReflectionModelServices类创建导入/导出定义,但仍有序列化和反序列化部分。任何人都可以点我的一些例子,文档或我提供建议,至于如何去了解这些步骤​​?

I think I can use the ReflectionModelServices class to create Import/Export definitions but that still leaves the serialization and deserialization parts. Can anybody point me to some examples, documentation or provide me with suggestion as to how to go about these steps?

推荐答案

这答案这个问题是由凯文在 MEF讨论列表提供。事实证明,人们可以从MEF的 ExportDefinition 和的 ImportDefinition 数据用下面的代码片段的结构。

This answer to this question was provided by Kevin on the MEF discussion list. It turns out that one can extract all the required information from the MEF ExportDefinition and ImportDefinition data structures with the following code snippets.

第一步是装配类型加载到目录中。然后在目录中的每个部分遍历进口和出口的定义。出口的定义只能放在类型,方法,属性和字段(其中我的代码忽略的时刻)。所以处理可以使用下面的代码出口

The first step is to load the assembly types into a catalog. Then for each part in the catalog iterate over the import and export definitions. Export definitions can only be placed on types, methods, properties and fields (which my code ignores at the moment). So to process the exports the following code can be used.

var exports = new List<Tuple<string, MemberInfo>>();
foreach (var export in part.ExportDefinitions)
{
    var memberInfo = ReflectionModelServices.GetExportingMember(export);
    Tuple<string, MemberInfo> exportDefinition = null;
    switch (memberInfo.MemberType)
    {
        case MemberTypes.Method:
            exportDefinition = new Tuple<string, MemberInfo>(export.ContractName, memberInfo.GetAccessors().First() as MethodInfo);
            break;
        case MemberTypes.NestedType:
        case MemberTypes.TypeInfo:
            exportDefinition = new Tuple<string, MemberInfo>(export.ContractName, memberInfo.GetAccessors().First() as Type);
            break;
        case MemberTypes.Property:
            // this is a bit ugly because we assume that the underlying methods for a property are named as:
            // get_PROPERTYNAME and set_PROPERTYNAME. In this case we assume that exports always
            // have a get method.
            var getMember = memberInfo.GetAccessors().Where(m => m.Name.Contains("get_")).First();
            var name = getMember.Name.Substring("get_".Length);
            var property = getMember.DeclaringType.GetProperty(name);
            exportDefinition = new Tuple<string, MemberInfo>(export.ContractName, property);
            break;

        default:
            throw new NotImplementedException();
    }

    exports.Add(exportDefinition);
}

为了处理进口,这只能放置在性能,参数和字段(这是再次被忽略)以下代码可用于:

In order to process the imports, which can only be placed on properties, parameters and fields (which are again ignored) the following code can be used:

public void ExtractImports()
{
    var imports = new List<Tuple<string, string>>();
    foreach (var import in part.ImportDefinitions)
    {
        SerializedImportDefinition importDefinition = !ReflectionModelServices.IsImportingParameter(import)
            ? importDefinition = CreatePropertyImport(import)
            : importDefinition = CreateConstructorParameterImport(import);
    }
}

private Tuple<string, string> CreatePropertyImport(ImportDefinition import)
{
    var memberInfo = ReflectionModelServices.GetImportingMember(import);
    if (memberInfo.MemberType != MemberTypes.Property)
    {
        throw new ArgumentOutOfRangeException("import");
    }

    // this is a bit ugly because we assume that the underlying methods for a property are named as:
    // get_PROPERTYNAME and set_PROPERTYNAME. In this case we assume that imports always
    // have a set method.
    var getMember = memberInfo.GetAccessors().Where(m => m.Name.Contains("set_")).First();
    var name = getMember.Name.Substring("set_".Length);
    var property = getMember.DeclaringType.GetProperty(name);
    return new Tuple<string, string>(import.ContractName, property.ToString());
}

private Tuple<string, string> CreateConstructorParameterImport(ImportDefinition import)
{
    var parameterInfo = ReflectionModelServices.GetImportingParameter(import);
    return new Tuple<string, string>(import.ContractName, parameterInfo.Value.ToString());
}

请注意,它似乎是进口无法通过方法参数提供,这样上面的代码不支持的。

Note that it seems that imports cannot be provided via method parameters so the code above does not support those.

一旦所有的出口和进口都已经被处理是序列化存储的的MemberInfo 对象转换为字符串格式。

Once all the exports and imports have been processed it is a simple question of serializing the stored MemberInfo objects into a string format.

这篇关于如何坚持MEF导入和导出信息到磁盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆