使用.NET的Reflection.Emit生成接口

时间:2020-03-06 14:45:13  来源:igfitidea点击:

我需要在运行时生成一个与现有接口具有所有相同成员的新接口,除了我将在某些方法上放置不同的属性(某些属性参数要等到运行时才能知道)。如何实现?

解决方案

问题不是很具体。如果我们使用更多信息对其进行更新,我将用更多详细信息充实该答案。

这是涉及的手动步骤的概述。

  • 使用DefineDynamicAssembly创建一个程序集
  • 使用DefineDynamicModule创建模块
  • 使用DefineType创建类型。确保传递TypeAttributes.Interface来使类型成为接口。
  • 遍历原始接口中的成员,并在新接口中构建相似的方法,并根据需要应用属性。
  • 调用TypeBuilder.CreateType完成界面的构建。

要使用具有属性的接口动态创建部件,请执行以下操作:

using System.Reflection;
using System.Reflection.Emit;

// Need the output the assembly to a specific directory
string outputdir = "F:\tmp\";
string fname = "Hello.World.dll";

// Define the assembly name
AssemblyName bAssemblyName = new AssemblyName();
bAssemblyName.Name = "Hello.World";
bAssemblyName.Version = new system.Version(1,2,3,4);

// Define the new assembly and module
AssemblyBuilder bAssembly = System.AppDomain.CurrentDomain.DefineDynamicAssembly(bAssemblyName, AssemblyBuilderAccess.Save, outputdir);
ModuleBuilder bModule = bAssembly.DefineDynamicModule(fname, true);

TypeBuilder tInterface = bModule.DefineType("IFoo", TypeAttributes.Interface | TypeAttributes.Public);

ConstructorInfo con = typeof(FunAttribute).GetConstructor(new Type[] { typeof(string) });
CustomAttributeBuilder cab = new CustomAttributeBuilder(con, new object[] { "Hello" });
tInterface.SetCustomAttribute(cab);

Type tInt = tInterface.CreateType();

bAssembly.Save(fname);

这将创建以下内容:

namespace Hello.World
{
   [Fun("Hello")]
   public interface IFoo
   {}
}

添加方法通过调用TypeBuilder.DefineMethod使用MethodBuilder类。