Мне нужно создать новый интерфейс во время выполнения со всеми теми же элементами, что и существующий интерфейс, за исключением того, что я буду добавлять разные атрибуты для некоторых методов (некоторые из них параметры атрибута неизвестны до времени выполнения). Как это можно достичь?Использование .NET Reflection.Emit для создания интерфейса
7
A
ответ
8
Ваш вопрос не очень конкретный. Если вы обновите его с дополнительной информацией, я подробно расскажу об этом ответе.
Вот краткий обзор предпринятых шагов.
- Создание сборки с DefineDynamicAssembly
- Создать модуль с DefineDynamicModule
- Создать тип с DefineType. Обязательно пройдите
TypeAttributes.Interface
, чтобы сделать свой тип интерфейсом. - Итерируйте элементы в исходном интерфейсе и создайте аналогичные методы в новом интерфейсе, применяя при необходимости атрибуты.
- Позвоните
TypeBuilder.CreateType
, чтобы завершить строительство вашего интерфейса.
12
Для динамического создания сборки с интерфейсом, который имеет атрибуты:
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
{}
}
методы Добавление использовать класс MethodBuilder по телефону TypeBuilder.DefineMethod.
Нет, это круто. Мне не нужно было использовать Reflection.Emit раньше, поэтому просто хотел посмотреть, сможет ли кто-нибудь обнаружить камень преткновения в моем злобном генеральном плане. –