2017-01-21 32 views
12

W języku C#, w jaki sposób wysyłać nowy typ w środowisku wykonawczym z .NET Core? Wszystkie przykłady, które mogę znaleźć dla .NET 6, nie działają w rdzeniu .NET (wszystkie zaczynają się od pobrania bieżącej AppDomain, która nie istnieje już w rdzeniu .NET).Jak emitować typ .NET Core

Jeśli to możliwe, doceniłbym przykład, który obejmuje tworzenie typu i dodawanie właściwości do typu.

Odpowiedz

20

tutaj tak pisać o tworząc rodzaj dynamicznej w .NET 4.

How to dynamically create a class in C#?

A w przyjętym odpowiedź jest tylko jedna wykorzystanie AppDomain.

AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); 

Oto kolejny SO pisać o wymianie DefineDynamicAssembly funkcji w .NET rdzenia.

Is there any replace of AssemblyBuilder.DefineDynamicAssembly in .NET Core?

Oto ona:

AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()),AssemblyBuilderAccess.Run); 

W "System.Reflection.Emit": "4.0.1" Nuget.

Istnieje również różnica w TypeBuilder. CreateType funkcja już nie istnieje, zamiast tego do tworzenia typów powinniśmy użyć CreateTypeInfo. I tak, to znowu z SO post.

CreateType missing from TypeBuilder. How to port this?

Tu pracuje zmodyfikowany przykład dla rdzenia (NET) tworzenia Rodzaj i dodawanie właściwości do Type.

using System; 
using System.Collections.Generic; 
using System.Reflection.Emit; 
using System.Reflection; 

namespace ConsoleApp1 
{ 
    public class FieldDescriptor 
    { 
     public FieldDescriptor(string fieldName, Type fieldType) 
     { 
      FieldName = fieldName; 
      FieldType = fieldType; 
     } 
     public string FieldName { get; } 
     public Type FieldType { get; } 
    } 

    public static class MyTypeBuilder 
    { 
     public static object CreateNewObject() 
     { 
      var myTypeInfo = CompileResultTypeInfo(); 
      var myType = myTypeInfo.AsType(); 
      var myObject = Activator.CreateInstance(myType); 

      return myObject; 
     } 

     public static TypeInfo CompileResultTypeInfo() 
     { 
      TypeBuilder tb = GetTypeBuilder(); 
      ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); 

      var yourListOfFields = new List<FieldDescriptor>() 
      { 
       new FieldDescriptor("YourProp1",typeof(string)), 
       new FieldDescriptor("YourProp2", typeof(int)) 
      }; 
      foreach (var field in yourListOfFields) 
       CreateProperty(tb, field.FieldName, field.FieldType); 

      TypeInfo objectTypeInfo = tb.CreateTypeInfo(); 
      return objectTypeInfo; 
     } 

     private static TypeBuilder GetTypeBuilder() 
     { 
      var typeSignature = "MyDynamicType"; 
      var an = new AssemblyName(typeSignature); 
      var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run); 
      ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); 
      TypeBuilder tb = moduleBuilder.DefineType(typeSignature, 
        TypeAttributes.Public | 
        TypeAttributes.Class | 
        TypeAttributes.AutoClass | 
        TypeAttributes.AnsiClass | 
        TypeAttributes.BeforeFieldInit | 
        TypeAttributes.AutoLayout, 
        null); 
      return tb; 
     } 

     private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) 
     { 
      FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); 

      PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); 
      MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); 
      ILGenerator getIl = getPropMthdBldr.GetILGenerator(); 

      getIl.Emit(OpCodes.Ldarg_0); 
      getIl.Emit(OpCodes.Ldfld, fieldBuilder); 
      getIl.Emit(OpCodes.Ret); 

      MethodBuilder setPropMthdBldr = 
       tb.DefineMethod("set_" + propertyName, 
        MethodAttributes.Public | 
        MethodAttributes.SpecialName | 
        MethodAttributes.HideBySig, 
        null, new[] { propertyType }); 

      ILGenerator setIl = setPropMthdBldr.GetILGenerator(); 
      Label modifyProperty = setIl.DefineLabel(); 
      Label exitSet = setIl.DefineLabel(); 

      setIl.MarkLabel(modifyProperty); 
      setIl.Emit(OpCodes.Ldarg_0); 
      setIl.Emit(OpCodes.Ldarg_1); 
      setIl.Emit(OpCodes.Stfld, fieldBuilder); 

      setIl.Emit(OpCodes.Nop); 
      setIl.MarkLabel(exitSet); 
      setIl.Emit(OpCodes.Ret); 

      propertyBuilder.SetGetMethod(getPropMthdBldr); 
      propertyBuilder.SetSetMethod(setPropMthdBldr); 
     } 
    } 
} 
Powiązane problemy