.net 动态程序集
最近有人问我是否了解 .Net 中的动态程序集。简短的回答是——我不喜欢。
我发现了很多描述如何创建动态程序集的文章,但没有一篇文章真正解释了以下内容:
- 它们是什么(除了直接从内存运行之外) 相
- 对于静态程序集,它们提供了哪些优势
- 其用法的真实示例
任何解释对以上内容将不胜感激。
非常感谢。
I was recently asked if I knew anything about Dynamic Assemblies in .Net. The short answer was - I don't.
I have found plenty of articles that describe how to create a dynamic assembly but none that truely explain the following:
- What they are (other than they are run directly from memory)
- What advantages they provide over static assemblies
- Real world examples of their usage
Any explanations to the above would be very much appreciated.
Many thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这篇文章有点过时了,代码有点“土气”,但我想说它是有关动态编译和一些突出问题的最容易理解的文章之一。
在这里,我学会了动态编译程序集,既可以在不需要卸载或控制安全性时在内存中编译,也可以通过远程处理加载临时文件以允许卸载。
一个真实的示例:一个在线 .net 正则表达式工具,它接受替换方法的 C# 代码,该方法动态编译到沙盒程序集中,用于执行替换并丢弃。这个策略效果很好,但是无论沙箱如何,恶意代码被注入的可能性都太大了,所以这个想法最终被放弃了。
祝你好运。
This article is a bit dated and the code is a bit 'rustic' but I would say it is one of the most accessible articles regarding dynamic compilation and some of the salient issues.
It is where I learned to compile assemblies on the fly, both in memory when I did not need to unload or control security, and to a temp file to be loaded with remoting to allow unloading.
A real world example: An online .net regex tool that accepts c# code for a replacer method that is dynamically compiled into a sandboxed assembly, used to perform the replacement and discarded. This strategy worked just fine, but the possibility of malicious code being injected regardless of sandboxing was just too great so the idea was eventually scrapped.
Good luck.
我将给您一些示例:
ASPNET 为每个 ASPX、ASMX 或 ASHX 生成程序集并动态加载它们。这里真正的好处是应用程序代码可以用模板语言部署,并且可以按需动态编译和运行。动态部分使得部署模型非常简单方便,也意味着效率:只有被调用的页面才会被实际加载。
DotNetZip 在保存自解压存档时创建动态程序集。实际上,它不是“从内存运行”,它最终会写入文件,因此这可能适合也可能不适合您对动态程序集的定义。程序集是在运行时动态创建的。但此时并没有调用它。为什么要动态创建呢?由于 exe 需要能够使用特定的 Win32 图标,因此它可能需要版本号和其他属性。这些东西可以在编译时设置。此外,程序集的源代码源自模板,使用调用者提供的各种数据来填充模板中的槽。因此,动态生成的程序集确实是正确的方法。
在 .NET 的 ASMX Web 服务框架中,wsdl.exe 编译器(或 xsd.exe 工具)将生成用于序列化/反序列化 XML 消息的类型。它通常会发出将 XML 元素建模为公共字段的类型。但是,虽然 DataGrid 和其他数据绑定控件可以使用数组
对象作为数据源,它们仅显示公共
属性。因此,应用程序无法执行 Web 服务调用、取回对象数组,然后将其指定为数据网格的源。我使用动态生成的程序集作为适配器,以允许数据驱动控件使用 Web 服务调用的输出。 [我认为,随着 ObjectDataSource 和 .NET 中的其他更改,这个问题已经消失了]。
在 .NET 内部,实例化特定类型的 System.Xml.Serialization.XmlSerializer 类会动态生成程序集。我认为这里的胜利与任何解释与编译的代码比较相同。在 xml 序列化中,基本思想是枚举类型的公共字段和属性,然后发出包含这些字段和属性中的值的 XML 文档。如果应用程序每次调用 XmlSerializer.Serialize() 时不必使用 System.Reflection 来枚举类型的成员(非常慢),那不是很好吗?
这是最近的一个 SO 问题,描述了有人想要创建动态程序集的场景:
如何使用代码生成动态创建 C# 方法?
I'll give you some examples:
ASPNET generates assemblies and loads them dynamically, for each ASPX, ASMX, or ASHX. The real benefit here is that the application code can be deployed in a template language, and can get dynamically compiled and run on demand. The dynamic part makes for a very simple and convenient deployment model, and also means efficiency: Only the pages that get called are actually loaded.
DotNetZip creates a dynamic assembly when saving a Self-Extracting archive. Actually it isn't "run from memory", it is written to a file, eventually, so this may or may not fit your definition for a dynamic assembly. The assembly is created dynamically, at runtime. But it is not invoked at that moment. Why create it dynamically? Because the exe needs to be able to use a particular Win32 Icon, it might need a version number and other properties. Those things can be set at compile time. Also, the source code for the assembly is derived from a template, using various data provided by the caller to fill in slots in the template. So a dynamically generated assembly is really the right way to go here.
In .NET's ASMX web services framework, the wsdl.exe compiler (or the xsd.exe tool) would produce types to serialize/deserialize XML messages. It would typically emit types that had the XML elements modelled as public fields. But while the DataGrid and other data-bound controls could use arrays of
objects as data sources, they displayed only public
properties. Therefore an app could not perform a webservices call, get back an array of objects, then assign that as the source for a Datagrid. I used a dynamically generated assembly as an Adapter to allow data-driven controls to consume the output of webservices calls. [This problem has since gone away, I think, with the ObjectDataSource and other changes in .NET].
Internally in .NET, instantiating the System.Xml.Serialization.XmlSerializer class for a particular type generates an assembly dynamically. I suppose the win here is the same as for any interpeted-vs-compiled code comparison. in xml serialization, the basic idea is to enumerate through a type's public fields and properties, and then emit an XML document that contains the values from those fields and props. Wouldn't it be nice if the app didn't have to use System.Reflection to enumerate a type's members (very slooooow), each time XmlSerializer.Serialize() is called?
Here's a recent SO question describing a scenario where someone wants to create a dynamic assembly:
How to use code generation to dynamically create C# methods?