2012-05-15 8 views
2

Я использую nBuilder для создания некоторых тестовых данных для моего приложения. Сначала я тестировал его, и он работал нормально. Простого пример:nBuilder Testdatagenerator и Reflection

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

Создает объект и заполняет все свойства автоматически. К примеру, если клиент содержит атрибут: имя, она заполнит его name1 и так далее ...

Ну это все работает нормально, но у меня есть проблемы, чтобы сделать все это динамически в настоящее время ,

Что я сейчас делаю, это Reflection, я повторяю все сущности в своем классе, и каждый из них должен создавать некоторые 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 
    { 
    } 
}