public void BuildRuntimeType_Struct_SetValue()
        {
            // Arrange
            SimpleStruct defaultStruct = new SimpleStruct
            {
                ValueType    = 50,
                ReferencType = "test data"
            };

            object setValue = null;

            Mock <IMockableRuntimeTypePropertyManager> managerMock = new Mock <IMockableRuntimeTypePropertyManager>(MockBehavior.Strict);

            managerMock.Setup(x => x.GetValue(nameof(InterfaceWithSimpleStruct.DefaultStruct)))
            .Returns(() => setValue);
            managerMock.Setup(x => x.SetValue(nameof(InterfaceWithSimpleStruct.DefaultStruct), It.IsAny <object>()))
            .Callback <string, object>((name, value) => setValue = value);

            var        manager   = managerMock.Object;
            MethodInfo getMethod = manager.GetType().GetMethod("GetValue");
            MethodInfo setMethod = manager.GetType().GetMethod("SetValue");

            // Act
            Stopwatch sw                   = Stopwatch.StartNew();
            Type      runtimeType          = RuntimeProxyBuilder.BuildRuntimeType(typeof(InterfaceWithSimpleStruct), getMethod, setMethod);
            InterfaceWithSimpleStruct impl = (InterfaceWithSimpleStruct)Activator.CreateInstance(runtimeType, manager);

            impl.DefaultStruct = defaultStruct;
            sw.Stop();
            Trace.WriteLine(sw.ElapsedMilliseconds);

            // Assert
            Assert.AreEqual(defaultStruct, impl.DefaultStruct);
        }
        public void BuildRuntimeType_MethodInterceptors_Function_InterceptClassMethod_ReturnParentValue()
        {
            // Arrange
            Mock <IMockableRuntimeTypePropertyManager> managerMock = new Mock <IMockableRuntimeTypePropertyManager>(MockBehavior.Strict);
            var        manager   = managerMock.Object;
            MethodInfo getMethod = manager.GetType().GetMethod("GetValue");
            MethodInfo setMethod = manager.GetType().GetMethod("SetValue");

            string expectedValue = "base";
            Func <Func <string>, string> interceptor = baseMethod => baseMethod();

            MethodInterceptions interceptions = new MethodInterceptions
            {
                Interceptions = new MethodInterception[]
                {
                    new DelegateMethodInterception
                    {
                        InterceptedMethod = typeof(ClassWithVirtualMethod).GetMethod(nameof(ClassWithVirtualMethod.FunctionToIntercept)),
                        Delegate          = interceptor
                    }
                }
            };

            // Act
            Stopwatch sw                = Stopwatch.StartNew();
            Type      runtimeType       = RuntimeProxyBuilder.BuildRuntimeType(typeof(ClassWithVirtualMethod), getMethod, setMethod, interceptions);
            ClassWithVirtualMethod impl = (ClassWithVirtualMethod)Activator.CreateInstance(runtimeType, new object[] { manager, interceptions });
            string returnedValue        = impl.FunctionToIntercept();

            sw.Stop();
            Trace.WriteLine(sw.ElapsedMilliseconds);

            // Assert
            Assert.AreEqual(expectedValue, returnedValue);
        }
        public void BuildRuntimeType_ReferenceType_GetValue()
        {
            // Arrange
            string value = "test value";

            Mock <IMockableRuntimeTypePropertyManager> managerMock = new Mock <IMockableRuntimeTypePropertyManager>(MockBehavior.Strict);

            managerMock.Setup(x => x.GetValue(nameof(ISimpleInterface.StringValue)))
            .Returns(value);

            var        manager   = managerMock.Object;
            MethodInfo getMethod = manager.GetType().GetMethod("GetValue");
            MethodInfo setMethod = manager.GetType().GetMethod("SetValue");

            // Act
            Stopwatch        sw            = Stopwatch.StartNew();
            Type             runtimeType   = RuntimeProxyBuilder.BuildRuntimeType(typeof(ISimpleInterface), getMethod, setMethod);
            ISimpleInterface impl          = (ISimpleInterface)Activator.CreateInstance(runtimeType, manager);
            string           returnedValue = impl.StringValue;

            sw.Stop();
            Trace.WriteLine(sw.ElapsedMilliseconds);

            // Assert
            Assert.AreEqual(value, returnedValue);
        }
        public void BuildRuntimeType_ReferenceType_SetValue()
        {
            // Arrange
            string value    = "test value";
            object setValue = null;
            Mock <IMockableRuntimeTypePropertyManager> managerMock = new Mock <IMockableRuntimeTypePropertyManager>(MockBehavior.Strict);

            managerMock.SetupGet(x => x.Implementation).Returns(null);
            managerMock.Setup(x => x.GetValue(nameof(ISimpleInterface.StringValue)))
            .Returns(() => setValue);
            managerMock.Setup(x => x.SetValue(nameof(ISimpleInterface.StringValue), It.IsAny <object>()))
            .Callback <string, object>((name, value) => setValue = value);

            var        manager   = managerMock.Object;
            MethodInfo getMethod = manager.GetType().GetMethod("GetValue");
            MethodInfo setMethod = manager.GetType().GetMethod("SetValue");

            // Act
            Stopwatch        sw          = Stopwatch.StartNew();
            Type             runtimeType = RuntimeProxyBuilder.BuildRuntimeType(typeof(ISimpleInterface), getMethod, setMethod);
            ISimpleInterface impl        = (ISimpleInterface)Activator.CreateInstance(runtimeType, manager);

            impl.StringValue = value;
            sw.Stop();
            Trace.WriteLine(sw.ElapsedMilliseconds);

            // Assert
            Assert.AreEqual(value, impl.StringValue);
        }
        public void BuildRuntimeType_Property_PreserveDefaultValue()
        {
            string propertyName      = nameof(ClassWithDefaultValue.PropertyWithDefaultValue);
            string defaultValue      = new ClassWithDefaultValue().PropertyWithDefaultValue;
            bool   setDefaultInvoked = false;

            Mock <IMockableRuntimeTypePropertyManager> managerMock = new Mock <IMockableRuntimeTypePropertyManager>(MockBehavior.Strict);

            managerMock.Setup(x => x.GetValue(propertyName))
            .Returns(null);
            managerMock.Setup(x => x.SetDefaultValue(propertyName, defaultValue)).Callback(() => setDefaultInvoked = true);

            var        manager   = managerMock.Object;
            MethodInfo getMethod = manager.GetType().GetMethod("GetValue");
            MethodInfo setMethod = manager.GetType().GetMethod("SetValue");

            // Act
            Stopwatch             sw          = Stopwatch.StartNew();
            Type                  runtimeType = RuntimeProxyBuilder.BuildRuntimeType(typeof(ClassWithDefaultValue), getMethod, setMethod);
            ClassWithDefaultValue impl        = (ClassWithDefaultValue)Activator.CreateInstance(runtimeType, manager);

            sw.Stop();
            Trace.WriteLine(sw.ElapsedMilliseconds);

            // Assert
            Assert.IsTrue(setDefaultInvoked);
        }
        public void BuildRuntimeType_MethodInterceptors_InterceptInterfaceMethod()
        {
            // Arrange
            Mock <IMockableRuntimeTypePropertyManager> managerMock = new Mock <IMockableRuntimeTypePropertyManager>(MockBehavior.Strict);
            var        manager   = managerMock.Object;
            MethodInfo getMethod = manager.GetType().GetMethod("GetValue");
            MethodInfo setMethod = manager.GetType().GetMethod("SetValue");

            bool   interceptorCalled = false;
            Action interceptor       = () => interceptorCalled = true;

            MethodInterceptions interceptions = new MethodInterceptions
            {
                Interceptions = new MethodInterception[]
                {
                    new DelegateMethodInterception
                    {
                        InterceptedMethod = typeof(IInterfaceWithMethod).GetMethod(nameof(IInterfaceWithMethod.MethodToIntercept)),
                        Delegate          = interceptor
                    }
                }
            };

            // Act
            Stopwatch            sw          = Stopwatch.StartNew();
            Type                 runtimeType = RuntimeProxyBuilder.BuildRuntimeType(typeof(IInterfaceWithMethod), getMethod, setMethod, interceptions);
            IInterfaceWithMethod impl        = (IInterfaceWithMethod)Activator.CreateInstance(runtimeType, new object[] { manager, interceptions });

            impl.MethodToIntercept();
            sw.Stop();
            Trace.WriteLine(sw.ElapsedMilliseconds);

            // Assert
            Assert.IsTrue(interceptorCalled);
        }
        public void BuildRuntimeType_MethodInterceptors_CallBase()
        {
            // Arrange
            Mock <IMockableRuntimeTypePropertyManager> managerMock = new Mock <IMockableRuntimeTypePropertyManager>(MockBehavior.Strict);
            var        manager   = managerMock.Object;
            MethodInfo getMethod = manager.GetType().GetMethod("GetValue");
            MethodInfo setMethod = manager.GetType().GetMethod("SetValue");

            Action <Action>     interceptor   = baseAction => baseAction();
            MethodInterceptions interceptions = new MethodInterceptions
            {
                Interceptions = new MethodInterception[]
                {
                    new DelegateMethodInterception
                    {
                        InterceptedMethod = typeof(ClassWithVirtualMethod).GetMethod(nameof(ClassWithVirtualMethod.ActionToIntercept)),
                        Delegate          = interceptor
                    }
                }
            };

            // Act
            Stopwatch sw                = Stopwatch.StartNew();
            Type      runtimeType       = RuntimeProxyBuilder.BuildRuntimeType(typeof(ClassWithVirtualMethod), getMethod, setMethod, interceptions);
            ClassWithVirtualMethod impl = (ClassWithVirtualMethod)Activator.CreateInstance(runtimeType, new object[] { manager, interceptions });

            impl.ActionToIntercept();
            sw.Stop();
            Trace.WriteLine(sw.ElapsedMilliseconds);

            // Assert
            Assert.IsTrue(impl.InterceptedMethodCalled);
        }
예제 #8
0
        public ProxyBuilder(Type proxiedType, ITypeIdentifier identifier, Guid creationContext)
        {
            this.identifier = identifier;
            Model           = ModelBuilder.New();
            Proxy           = RuntimeProxyBuilder.BuildDynamicProxy(proxiedType, creationContext);

            ProxiedType = proxiedType;
        }
        static RuntimeProxyManager()
        {
            Type currentType = typeof(RuntimeProxyManager <TInterface>);

            /**** RuntimeType ****/
            getMethod = currentType.GetMethod(nameof(GetValue));
            setMethod = currentType.GetMethod(nameof(SetValue));
            runtimeTypeWithoutInterceptions = new Lazy <Type>(() => RuntimeProxyBuilder.BuildRuntimeType(typeof(TInterface), getMethod, setMethod, null));
        }
예제 #10
0
        public void AddContract(Type contractType)
        {
            if (!ContractTypes.Add(contractType))
            {
                throw new ArgumentException($"Contract `{contractType.Name}` has already been registered.");
            }

            Type contractProxy = RuntimeProxyBuilder.BuildRuntimeType(contractType);

            Type runtimeProxyType = typeof(RuntimeProxy <>).MakeGenericType(contractType);

            services.AddTransient(runtimeProxyType);
            services.AddTransient(contractType, contractProxy);
        }
예제 #11
0
        public void AddContract <TContract>() where TContract : class
        {
            Type contractType = typeof(TContract);

            if (!ContractTypes.Add(contractType))
            {
                throw new ArgumentException($"Contract `{contractType.Name}` has already been registered.");
            }

            Type contractProxy = RuntimeProxyBuilder.BuildRuntimeType(contractType);

            services.AddTransient <RuntimeProxy <TContract> >();
            services.AddTransient(contractType, contractProxy);
        }
        private static Type GetRuntimeType(MethodInterceptions interceptions)
        {
            if (interceptions == null)
            {
                return(runtimeTypeWithoutInterceptions.Value);
            }

            Type type;

            lock (typeof(TInterface))
            {
                if (!typeCache.TryGetValue(interceptions, out type))
                {
                    type = RuntimeProxyBuilder.BuildRuntimeType(typeof(TInterface), getMethod, setMethod, interceptions);
                    typeCache.Add(interceptions, type);
                }
            }

            return(type);
        }