예제 #1
0
        public void CreateTypeForComplexInterface()
        {
            Type iClass = DynamicTypeGenerator.GetTypeForInterface(typeof(IComplexInterface));

            IComplexInterface instance = (IComplexInterface)Activator.CreateInstance(iClass);

            instance.ShouldNotBeNull();

            instance.Id          = 42;
            instance.Foo         = new Foo();
            instance.NullableInt = 123;
            instance.Name        = "Lorem ipsum";
            instance.Ints        = new List <int>();
            instance.IntArray    = new int[2];
            instance.Foos        = new List <Foo>();
            instance.FooArray    = new Foo[2];

            instance.Id.ShouldBe(42);
            instance.Foo.ShouldNotBeNull();
            instance.NullableInt.ShouldBe(123);
            instance.Name.ShouldBe("Lorem ipsum");

            int    i = 0;
            string s = null;

            Should.Throw <NotImplementedException>(() => instance.BaseMethod(), "Call BaseMethod.");
            Should.Throw <NotImplementedException>(() => instance.SimpleMethod(), "Call SimpleMethod.");
            Should.Throw <NotImplementedException>(() => instance.ComplexMethod(123, ref i, out s), "Call ComplexMethod.");
        }
예제 #2
0
        public void ThrowExceptionWhenInterfaceIsNotVisible()
        {
            void action() => DynamicTypeGenerator.GetTypeForInterface(typeof(INotVisibleInterface));

            var ex = Should.Throw <InvalidOperationException>(action);

            ex.Message.ShouldContain("not accessible");
        }
예제 #3
0
        public void CreateTypeForSimpleInterface()
        {
            Type iClass = DynamicTypeGenerator.GetTypeForInterface(typeof(ISimpleInterface));

            ISimpleInterface instance = (ISimpleInterface)Activator.CreateInstance(iClass);

            instance.ShouldNotBeNull();

            instance.Id   = 42;
            instance.Name = "Lorem ipsum";

            instance.Id.ShouldBe(42);
            instance.Name.ShouldBe("Lorem ipsum");
        }
예제 #4
0
        protected virtual Expression CreateInstantiationExpression(Expression source, Expression?destination, CompileArgument arg)
        {
            //new TDestination()

            //if there is constructUsing, use constructUsing
            var constructUsing = arg.GetConstructUsing();

            if (constructUsing != null)
            {
                var args = destination == null ? new[] { source } : new[] { source, destination };
                return(constructUsing.Apply(arg.MapType, args)
                       .TrimConversion(true)
                       .To(arg.DestinationType));
            }

            //if there is default constructor, use default constructor
            else if (arg.DestinationType.HasDefaultConstructor())
            {
                return(Expression.New(arg.DestinationType));
            }

            //if mapToTarget or include derived types, allow mapping & throw exception on runtime
            //instantiation is not needed
            else if (destination != null || arg.Settings.Includes.Count > 0)
            {
                return(Expression.Throw(
                           Expression.New(
                               // ReSharper disable once AssignNullToNotNullAttribute
                               typeof(InvalidOperationException).GetConstructor(new[] { typeof(string) }),
                               Expression.Constant("Cannot instantiate type: " + arg.DestinationType.Name)),
                           arg.DestinationType));
            }

            //if mapping to interface, create dynamic type implementing it
            else if (arg.DestinationType.GetTypeInfo().IsInterface)
            {
                return(Expression.New(DynamicTypeGenerator.GetTypeForInterface(arg.DestinationType)));
            }

            //otherwise throw
            else
            {
                throw new InvalidOperationException($"No default constructor for type '{arg.DestinationType.Name}', please use 'ConstructUsing' or 'MapWith'");
            }
        }
예제 #5
0
        protected override Expression CreateInstantiationExpression(Expression source, Expression?destination, CompileArgument arg)
        {
            //new TDestination(src.Prop1, src.Prop2)

            if (arg.GetConstructUsing() != null)
            {
                return(base.CreateInstantiationExpression(source, destination, arg));
            }

            var destType = arg.DestinationType.GetTypeInfo().IsInterface
                ? DynamicTypeGenerator.GetTypeForInterface(arg.DestinationType)
                : arg.DestinationType;
            var ctor           = destType.GetConstructors()[0];
            var classModel     = GetConstructorModel(ctor, false);
            var classConverter = CreateClassConverter(source, classModel, arg);

            return(CreateInstantiationExpression(source, classConverter, arg));
        }
예제 #6
0
        protected override Expression CreateInstantiationExpression(Expression source, Expression?destination, CompileArgument arg)
        {
            //new TDestination(src.Prop1, src.Prop2)

            if (arg.GetConstructUsing() != null || arg.Settings.MapToConstructor == null)
            {
                return(base.CreateInstantiationExpression(source, destination, arg));
            }

            ClassMapping?classConverter;
            var          ctor = arg.Settings.MapToConstructor as ConstructorInfo;

            if (ctor == null)
            {
                var destType = arg.DestinationType.GetTypeInfo().IsInterface
                    ? DynamicTypeGenerator.GetTypeForInterface(arg.DestinationType, arg.Settings.Includes.Count > 0)
                    : arg.DestinationType;
                if (destType == null)
                {
                    return(base.CreateInstantiationExpression(source, destination, arg));
                }
                classConverter = destType.GetConstructors()
                                 .OrderByDescending(it => it.GetParameters().Length)
                                 .Select(it => GetConstructorModel(it, true))
                                 .Select(it => CreateClassConverter(source, it, arg))
                                 .FirstOrDefault(it => it != null);
            }
            else
            {
                var model = GetConstructorModel(ctor, false);
                classConverter = CreateClassConverter(source, model, arg);
            }

            if (classConverter == null)
            {
                return(base.CreateInstantiationExpression(source, destination, arg));
            }

            return(CreateInstantiationExpression(source, classConverter, arg));
        }