2012-05-15 45 views
2

我使用nBuilder爲我的應用程序生成一些Testdata。 首先我測試它,它工作正常。 一個簡單的例子:nBuilder Testdatagenerator和Reflection

Customer customer = Builder<Customer> 
        .CreateNew() 
        .Build(); 

創建一個對象,並自動填充的所有屬性。 通過舉例來說,如果客戶包含屬性:,它將與名1 等填充...

嗯,這一切工作正常,但我有麻煩做整個事情現在動態。

我現在正在做的是反射,我遍歷所有實體在我的類和foreach他們應該產生一些Testdata,甚至查找和兒童名單應該填充,但多數民衆贊成在一個問題..我的問題是,我如何使用以上代碼與任何類型?

ANYTYPE object = Builder<ANYTYPE> ...

我試了一下:

object entity = null; //The object/Entity 
Assembly assembly = Assembly.GetAssembly(typeof(EMI_ERPContext)); //Getting Assembly 
Type type = assembly.GetType(entityName); //I know the Type 
//entity = Activator.CreateInstance(type); Do I must create an Instance here? 
object entity = Builder<dynamic> //The above code.. Tried to put dynamic as Type, but doesnt work 
       .CreateNew() 
       .Build(); 

回答

2

我有一個控制檯應用程序測試(完成這裏),僞造nBuilder的類/接口/方法。

所以這個工作,但沒有在真正的情況下嘗試。

您可以重複使用的方法是「TryToReflectBuilder」。它可能不那麼冗長,但我讓「一步一步」的代碼,因爲它可能更明確。 ReflectionConsole.Test被用作「反映的實體」。

namespace ReflectionConsole { 
    class Program { 
     static void Main(string[] args) 
     { 

      object test = TryToReflectBuilder("ReflectionConsole.Test"); 
      Console.ReadKey(); 
     } 

     public static object TryToReflectBuilder(string type) 
     { 
      //getting the assembly : not same as your way, but... that wasn't a problem for you 
      var assembly = Assembly.GetAssembly(typeof(Test)); 

      //getting the entityType by name. 
      var entityType = assembly.GetType(type); 

      //The interesting (I hope) part is starting (yeah) 
      //get the Builder<T> type 
      var builderClassType = typeof(Builder<>); 

      //create generic argument for Builder<T> will take the type of our entity (always an array) 
      Type[] args = {entityType}; 

      //pass generic arguments to Builder<T>. Which becomes Builder<entityType> 
      var genericBuilderType = builderClassType.MakeGenericType(args); 

      //create a new instance of Builder<entityType> 
      var builder = Activator.CreateInstance(genericBuilderType); 

      //retrieve the "CreateNew" method, which belongs to Builder<T> class 
      var createNewMethodInfo = builder.GetType().GetMethod("CreateNew"); 

      //invoke "CreateNew" from our builder instance which gives us an ObjectBuilder<T>, so now an ObjectBuilder<entityType> (well as an ISingleObjectBuilder<entityType>, but... who minds ;)) 
      var objectBuilder = createNewMethodInfo.Invoke(builder, null); 

      //retrieve the "Build" method, which belongs to ObjectBuilder<T> class 
      var buildMethodInfo = objectBuilder.GetType().GetMethod("Build"); 

      //finally, invoke "Build" from our ObjectBuilder<entityType> instance, which will give us... our entity ! 
      var result = buildMethodInfo.Invoke(objectBuilder, null); 

      //it would be sad to return nothing after all these efforts, no ?? 
      return result; 
     } 
    } 

    public class Builder<T> 
    { 
     public static ISingleObjectBuilder<T> CreateNew() 
     { 
      Console.WriteLine(string.Format("{0} creating new",typeof(T))); 
      return new ObjectBuilder<T>(); 
     } 
    } 

    public interface ISingleObjectBuilder<T> : IBuildable<T> 
    { 
    } 
    public interface IObjectBuilder<T> : ISingleObjectBuilder<T> 
    { 

    } 
    public interface IBuildable<T> 
    { 
     T Build(); 
    } 

    public class ObjectBuilder<T> : ISingleObjectBuilder<T> 
    { 
     public T Build() 
     { 
      Console.WriteLine(string.Format("{0} building myself", typeof(T))); 
      return Activator.CreateInstance<T>(); 
     } 
    } 

    public class Test 
    { 
    } 
}