2

nBuilderを使用して、アプリケーションのテストデータを生成しています。最初に私はそれをテストしました、そしてそれはうまくいきました。簡単な例:

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

オブジェクトを作成し、すべてのプロパティを自動的に入力します。たとえば、customerに属性nameが含まれている場合、 name1 などで埋められます。

これはすべてうまくいきますが、今はすべてを動的に行うのに苦労しています。

私が今しているのはReflectionです。クラス内のすべてのエンティティを反復処理しており、各エンティティに対してテストデータを生成し、ルックアップや子リストも入力する必要がありますが、それは問題ではありません。上記のコードを任意のタイプでどのように使用していますか?

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();
4

1 に答える 1

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
    {
    }
}
于 2012-05-15T22:30:04.660 に答える