2012-04-09 10 views
9

Tôi có các lớp sau:Loại động Sáng tạo với một Constructor tham chiếu phụ thuộc của nó

public class Entity<T> where T : Entity<T> { 
    public Factory<T> Factory { get; private set; } 
    public Entity(Factory<T> factory) { 
     Factory = factory; 
    } 
} 
public class Factory<T> { } 

public class MyEntity : Entity<MyEntity> { 
    public MyEntity(Factory<MyEntity> factory) : base(factory) { } 
} 

tôi đang cố gắng để tự động tạo ra lớp MyEntity với các nhà xây dựng theo quy định. Cho đến nay tôi có đoạn mã sau:

class Program { 
    static ModuleBuilder _moduleBuilder; 
    public static ModuleBuilder ModuleBuilder { 
     get { 
      if (_moduleBuilder == null) { 
       AssemblyBuilder asmBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(new AssemblyName("Dynamic"), AssemblyBuilderAccess.Run); 
       _moduleBuilder = asmBuilder.DefineDynamicModule("MainModule"); 
      } 
      return _moduleBuilder; 
     } 
    } 

    static void Main(string[] args) { 
     TypeBuilder typeBuilder = ModuleBuilder.DefineType("MyEntity", TypeAttributes.Public); 
     Type baseType = typeof(Entity<>).MakeGenericType(typeBuilder); 
     typeBuilder.SetParent(baseType); 

     Type factoryType = typeof(Factory<>).MakeGenericType(typeBuilder); 


     ConstructorBuilder cBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { factoryType }); 
     ILGenerator ctorIL = cBuilder.GetILGenerator(); 
     ctorIL.Emit(OpCodes.Ldarg_0); 
     ctorIL.Emit(OpCodes.Ldarg_1); 
     ConstructorInfo c = baseType.GetConstructor(new Type[] { factoryType }); 
     ctorIL.Emit(OpCodes.Call, c); 
     ctorIL.Emit(OpCodes.Ret); 

     Type syType = typeBuilder.CreateType(); 
     Console.ReadLine(); 
    } 
} 

Mã không thành công @ConstructorInfo c = baseType.GetConstructor(new Type[] { factoryType }). Tôi nhận được một NotSupportedException.

Có cách nào để đạt được điều này không? Tôi đã bị stonewalled bởi điều này trong ba ngày. Bất kỳ trợ giúp sẽ được đánh giá cao.

Cảm ơn!

+1

Gọi Eric Lippert, Eric Lippert? – Joe

+2

@JoeTuskan: Tôi không nghĩ mình cần ở đây; đây là một câu hỏi đơn giản về Reflection. –

Trả lời

3

Bạn cần sử dụng phương thức tĩnh TypeBuilder.GetConstructor. Tôi nghĩ rằng điều này sẽ hoạt động (chưa được kiểm tra):

ConstructorInfo genCtor = typeof(Entity<>).GetConstructor(new Type[] { typeof(Factory<>).MakeGenericType(typeof(Entity<>).GetGenericArguments()) }); 
ConstructorInfo c = TypeBuilder.GetConstructor(baseType, genCtor);