如何在运行时向DLL添加代码

时间:2023-01-27 13:32:24

Let's say in the constructor of my .NET class I want to write code that will actually add methods to my class dynamically. So now when I reflect over my class I will see the methods where as when I first built the project the methods didn't exist

让我们说在我的.NET类的构造函数中,我想编写实际上会动态地向我的类添加方法的代码。所以现在当我反思我的课时,我会看到方法,当我第一次构建项目时,方法不存在

How can I achieve this?

我怎样才能做到这一点?

I've been looking up CodeDom but it's all a bit confusing

我一直在寻找CodeDom,但它有点令人困惑

5 个解决方案

#1


Once you've loaded the assembly, you cannot change it. You can use Reflection.Emit or CodeDom to dynamically compile a new assembly, with a class that is just like yours + extra methods, but it will not change the existing (at least existing at runtime) class. Potentially, you could load your class in a separate AppDomain, create a new class that was a "copy" of it with the extras, then load that assembly in your main AppDomain (and unload the one where you loaded your original class). You're still creating a new class, not adding to an existing one, but the effect would be similar.

加载程序集后,无法更改它。您可以使用Reflection.Emit或CodeDom动态编译新程序集,其类似于您的类+额外方法,但它不会更改现有(至少在运行时存在)类。潜在地,您可以在单独的AppDomain中加载您的类,创建一个新的类,它是附加的“副本”,然后在主AppDomain中加载该程序集(并卸载您加载原始类的那个)。您仍然在创建一个新类,而不是添加到现有类,但效果类似。

You can use code injection to insert code before the class is loaded, however. There are some code injection frameworks for .NET that would help with this... but that is different than your specific question.

但是,您可以在加载类之前使用代码注入来插入代码。有一些.NET的代码注入框架可以帮助解决这个问题......但这与您的具体问题不同。

#2


you have to either use Reflection.Emit or Mono.Cecil or PostSharp.

你必须使用Reflection.Emit或Mono.Cecil或PostSharp。

All of them are easy to learn...

所有这些都很容易学习......

#3


I.... can't imagine why you would want to do this.

我......无法想象你为什么要这样做。

Could you explain why you would want to?

你能解释一下你想要的原因吗?

Instead, try having different concrete implementations of the same interface, or abstract class if you're sharing most of the code.

相反,尝试使用相同接口的不同具体实现,或者如果共享大部分代码,则使用抽象类。

#4


You can do that without learning anything extra using CInject (open source at Codeplex). Write the code to be injected in C# or VB.NET and then get it processed through CInject to be added into a managed assembly.

你可以在不使用CInject(Codeplex的开源)学习任何额外内容的情况下做到这一点。编写要在C#或VB.NET中注入的代码,然后通过CInject处理它以添加到托管程序集中。

#5


I agree with @reed-copsey using appdomain domcomplie functions. You can make a plugin class that inherits a plugin base class, you can add all the Classes you want. When it compiles in the appdomain it will even be able to give you coding errors that were injected into that class. It then wont compile that specfic class. At least you will know the code has a problem.

我赞同@ reed-copsey使用appdomain domcomplie函数。您可以创建一个继承插件基类的插件类,您可以添加所需的所有类。当它在appdomain中编译时,它甚至可以为你提供注入该类的编码错误。然后它不会编译那个specfic类。至少你会知道代码有问题。

#1


Once you've loaded the assembly, you cannot change it. You can use Reflection.Emit or CodeDom to dynamically compile a new assembly, with a class that is just like yours + extra methods, but it will not change the existing (at least existing at runtime) class. Potentially, you could load your class in a separate AppDomain, create a new class that was a "copy" of it with the extras, then load that assembly in your main AppDomain (and unload the one where you loaded your original class). You're still creating a new class, not adding to an existing one, but the effect would be similar.

加载程序集后,无法更改它。您可以使用Reflection.Emit或CodeDom动态编译新程序集,其类似于您的类+额外方法,但它不会更改现有(至少在运行时存在)类。潜在地,您可以在单独的AppDomain中加载您的类,创建一个新的类,它是附加的“副本”,然后在主AppDomain中加载该程序集(并卸载您加载原始类的那个)。您仍然在创建一个新类,而不是添加到现有类,但效果类似。

You can use code injection to insert code before the class is loaded, however. There are some code injection frameworks for .NET that would help with this... but that is different than your specific question.

但是,您可以在加载类之前使用代码注入来插入代码。有一些.NET的代码注入框架可以帮助解决这个问题......但这与您的具体问题不同。

#2


you have to either use Reflection.Emit or Mono.Cecil or PostSharp.

你必须使用Reflection.Emit或Mono.Cecil或PostSharp。

All of them are easy to learn...

所有这些都很容易学习......

#3


I.... can't imagine why you would want to do this.

我......无法想象你为什么要这样做。

Could you explain why you would want to?

你能解释一下你想要的原因吗?

Instead, try having different concrete implementations of the same interface, or abstract class if you're sharing most of the code.

相反,尝试使用相同接口的不同具体实现,或者如果共享大部分代码,则使用抽象类。

#4


You can do that without learning anything extra using CInject (open source at Codeplex). Write the code to be injected in C# or VB.NET and then get it processed through CInject to be added into a managed assembly.

你可以在不使用CInject(Codeplex的开源)学习任何额外内容的情况下做到这一点。编写要在C#或VB.NET中注入的代码,然后通过CInject处理它以添加到托管程序集中。

#5


I agree with @reed-copsey using appdomain domcomplie functions. You can make a plugin class that inherits a plugin base class, you can add all the Classes you want. When it compiles in the appdomain it will even be able to give you coding errors that were injected into that class. It then wont compile that specfic class. At least you will know the code has a problem.

我赞同@ reed-copsey使用appdomain domcomplie函数。您可以创建一个继承插件基类的插件类,您可以添加所需的所有类。当它在appdomain中编译时,它甚至可以为你提供注入该类的编码错误。然后它不会编译那个specfic类。至少你会知道代码有问题。