Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建和使用仅.NET元数据';参考组件';?_C#_.net_Assemblies - Fatal编程技术网

C# 如何创建和使用仅.NET元数据';参考组件';?

C# 如何创建和使用仅.NET元数据';参考组件';?,c#,.net,assemblies,C#,.net,Assemblies,由于3.0版,.NET在C:\Program Files\reference Assembly\Microsoft….下安装了一组不同的“引用程序集”,以支持不同的配置文件(例如.NET 3.5客户端配置文件、Silverlight配置文件)。每个程序集都是一个正确的.NET程序集,只包含元数据,不包含IL代码,并且每个程序集都用ReferenceAssemblyAttribute标记。元数据仅限于适用概要文件下可用的类型和成员-这就是intellisense显示受限类型和成员集的方式。在运行时

由于3.0版,.NET在C:\Program Files\reference Assembly\Microsoft….下安装了一组不同的“引用程序集”,以支持不同的配置文件(例如.NET 3.5客户端配置文件、Silverlight配置文件)。每个程序集都是一个正确的.NET程序集,只包含元数据,不包含IL代码,并且每个程序集都用
ReferenceAssemblyAttribute
标记。元数据仅限于适用概要文件下可用的类型和成员-这就是intellisense显示受限类型和成员集的方式。在运行时不使用引用程序集

我从中学到了一点

我想为我的库创建并使用这样的引用程序集

  • 如何创建仅元数据程序集-是否有编译器标志或ildasm后处理器
  • 是否存在控制哪些类型导出到不同“配置文件”的属性
  • 运行时引用程序集解析如何-如果我的应用程序目录中存在引用程序集而不是“真实”程序集,并且根本不在GAC中,那么探测会继续并触发我的AssemblyResolve事件,以便我可以在运行时提供实际的程序集
  • 如有任何想法或建议,我将不胜感激

    更新:环顾四周,我看到.NET3.0的“引用程序集”似乎确实有一些代码,并且只在.NET4.0中添加了。因此,在新的运行时中,行为可能发生了一些变化

    为什么??对于我的Excel DNA()外接程序库,我通过将引用的程序集作为资源打包到.xll文件中来创建单个文件.xll外接程序。打包的程序集包括用户的外接程序代码以及Excel DNA托管库(用户的程序集可能会引用该库)

    它听起来相当复杂,但在大多数情况下工作得非常好-外接程序是一个小文件,因此没有安装分发问题。由于版本不同,我遇到了(并非意外的)问题-如果有旧版本的Excel DNA托管库作为文件,运行时将加载该文件,而不是打包的文件(我从未有机会干扰加载)


    我希望为我的Excel DNA管理部件制作一个参考程序集,用户可以在编译外接程序时指向它。但是,如果他们在运行时错误地拥有此程序集的版本,则运行时将无法加载它,并让我有机会从资源中加载真实的程序集。

    要创建引用程序集,请将此行添加到
    AssemblyInfo.cs
    文件中:

    [assembly: ReferenceAssembly]
    
    要加载其他对象,您可以像往常一样从VisualStudio项目引用中引用它们,或者在运行时使用以下方法动态引用它们:


    如果您使用VisualStudio向元数据/引用程序集添加了引用,则intellisense和构建项目将正常工作,但是如果您尝试针对某个组件执行应用程序,则会出现错误:

    System.BadImageFormatException:无法加载引用程序集以执行

    因此,期望在运行时替换具有相同元数据签名的真实程序集

    如果已使用
    assembly.ReflectionOnlyLoad()
    动态加载程序集,则只能对其执行所有反射操作(读取类型、方法、属性、属性等,但不能动态调用其中任何一个)



    我很好奇您创建仅元数据程序集的用例是什么。我以前从未这样做过,我很想知道您是否发现了它们的一些有趣的用途…

    是的,这是.NET 4.0的新功能。我相当肯定这样做是为了避免.NET2.0服务包中令人讨厌的版本控制问题。最好的例子是在SP2中添加并记录的WaitHandle.WaitOne(int)重载。一种流行的重载,因为它避免了在WaitOne(int,bool)重载中猜测*exitContext”的正确值。问题是,当程序在早于SP2的2.0版本上运行时,它会爆炸。这也不是一种令人满意的诊断。隔离引用程序集可确保不会再次发生这种情况


    我认为这些引用程序集是从编译程序集的副本开始创建的(就像在以前的版本中一样)并通过一个从程序集中剥离IL的工具来运行它们。但是,我们无法使用该工具,bin/netfx 4.0 tools Windows 7.1 SDK子目录中没有任何工具可以做到这一点。这不是一个经常使用的工具,因此可能不是生产质量:)

    您可能会很幸运地使用Cecil库(来自Mono);我认为该实现允许ILMerge功能,也可以只编写元数据程序集

    我已经扫描了代码库(文档很少),但还没有找到任何明显的线索


    YYMV

    如果您仍然对这种可能性感兴趣,我已经基于Mono.Cecil创建了一个il重新打包项目的分支,它接受一个“/meta”命令行参数,为公共和受保护的类型生成一个仅元数据的程序集


    (我在完整的XNA框架上进行了尝试,并在afaik中运行……)

    制作一个精心设计的示例:您可以使用Mono mkbundle.exe等创建.NET程序集的本机映像。现在您仍然可以允许插件DLL访问原始程序集的公共接口。我相信您可以这样做。如果有任何问题,它会导致程序集变得非常混乱和庞大:)添加引用embly属性不会将输出更改为仅元数据程序集,如.NET 4引用程序集。我正在尝试了解这些程序集是如何生成的。我必须尝试,但在处理BadImageFormatException后,您认为程序集解析是否会调用我的AssemblyResolve处理程序?(我将