public void BuildProxyType_VirtualPublicProperty_WithSetter()
        {
            var knownBaseTypes = new[] { typeof(ProxiedChild) };
            //var knownInterfaceTypes = new[] { typeof (IProperty) };
            var knownTypes  = knownBaseTypes; //knownBaseTypes.Union (knownInterfaceTypes).ToArray ();
            var typeFilter  = new TypeLevelTypeFilter(knownTypes);
            var proxiedType = typeof(ProxiedChildChildChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_PublicProperty"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            // Create proxy instance, initializing it with class to be proxied
            var    proxied = new ProxiedChildChildChild("PC");
            object proxy   = Activator.CreateInstance(proxyType, proxied);

            Assert.That(proxied.MutableNamePropertyVirtual, Is.EqualTo("ProxiedChildChild::MutableNamePropertyVirtual PC"));

            //To.ConsoleLine.e ("proxyType.GetAllProperties()", proxyType.GetAllProperties ()).nl ().e (proxyType.GetAllProperties ().Select (pi => pi.Attributes)).nl (2).e ("proxyType.GetAllMethods()", proxyType.GetAllMethods ());

            var proxyPropertyInfo = proxyType.GetProperty("MutableNamePropertyVirtual", _publicInstanceFlags);


            // Note: Virtual properties remain virtual, so the proxy calls go to ProxiedChildChild, not the first known base type of ProxiedChild
            // (ProxiedChildChildChild does not override MutableNamePropertyVirtual).

            Assert.That(proxyPropertyInfo, Is.Not.Null);
            Assert.That(proxyPropertyInfo.CanRead, Is.True);
            Assert.That(proxyPropertyInfo.CanWrite, Is.True);
            Assert.That(proxyPropertyInfo.GetValue(proxy, null), Is.EqualTo("ProxiedChildChild::MutableNamePropertyVirtual PC"));

            proxyPropertyInfo.SetValue(proxy, "XXyyZZ", null);
            Assert.That(proxyPropertyInfo.GetValue(proxy, null), Is.EqualTo("ProxiedChildChild::MutableNamePropertyVirtual XXyyZZ-ProxiedChildChild::MutableNamePropertyVirtual"));
        }
        private void Assert_BuildProxyType_GenericClassesAndMethods(
            Type knownBaseType, Type[] knownInterfaceTypes, Type proxiedType)
        {
            var knownTypes = knownInterfaceTypes.Concat(new[] { knownBaseType }).ToArray();
            var typeFilter = new TypeLevelTypeFilter(knownTypes);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_MultipleKnownInterfaces_PublicAndExplicitInterfaceImplementation"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            var knownBaseTypeMethods = knownBaseType.GetMethods().Where(m => m.IsSpecialName == false);
            var proxyMethods         = proxyType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(m => m.IsSpecialName == false && m.DeclaringType != typeof(Object)).ToArray();
            var interfaceMethods     = knownInterfaceTypes.SelectMany(t => t.GetMethods(BindingFlags.Instance | BindingFlags.Public));

            //To.ConsoleLine.e (knownBaseTypeMethods).nl (3).e (interfaceMethods).nl (3).e (proxyMethods).nl (3);

            var numberKnownBaseTypeMethods = knownBaseTypeMethods.Count();
            var numberInterfaceMethods     = interfaceMethods.Count();
            var numberProxyMethods         = proxyMethods.Count();

      #if (true)
            Assert.That(numberKnownBaseTypeMethods + numberInterfaceMethods + typeof(IProxy).GetMethods().Length, // + typeof (IProxy).GetMethods ().Length,
                        Is.EqualTo(numberProxyMethods));
      #endif

            AssertHasSameMethod(knownBaseType, proxyType, "ProxiedChildGenericToString", typeof(int), typeof(string));
        }
        private void AssertGetFirstKnownBaseType(Type proxiedType, TypeLevelTypeFilter typeFilter, Type expectedType)
        {
            var moduleScopeStub           = MockRepository.GenerateStub <ModuleScope>();
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, moduleScopeStub);

            Assert.That(stableBindingProxyBuilder.GetFirstKnownBaseType(), Is.EqualTo(expectedType));
        }
        public void BuildProxyType_ComplexGenericArguments_Virtual()
        {
            var knownBaseType             = typeof(ProxiedChildGeneric <Proxied, Document>);
            var typeFilter                = new TypeLevelTypeFilter(new[] { knownBaseType });
            var proxiedType               = typeof(ProxiedChildChildGeneric <Proxied, Document>);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_CheckInterfaceMembers"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            const string methodName = "ProxiedChildGeneric_ComplexGenericArguments_Virtual";

            AssertHasSameGenericMethod(knownBaseType, proxyType, methodName, 2);

            var proxied = new ProxiedChildChildGeneric <Proxied, Document> ();

            var proxyMethodGeneric = GetGenericMethod(proxyType, methodName, 2);

            Assert.That(proxyMethodGeneric.IsGenericMethod, Is.True);

            var proxyMethod = proxyMethodGeneric.MakeGenericMethod(typeof(string), typeof(int));

            var proxy = Activator.CreateInstance(proxyType, proxied);

            var          p0 = new Proxied("Hello");
            var          p1 = new Document("Doc");
            const string p2 = "xyz";
            const int    p3 = 1234567;

            var methodArguments = Create_ProxiedChildGeneric_ComplexGenericArguments_Parameters(p0, p1, p2, p3);

            var proxyResult = (string)proxyMethod.Invoke(proxy, methodArguments);

            StringAssert.StartsWith("ProxiedChildGeneric::ProxiedChildGeneric_ComplexGenericArguments_Virtual", proxyResult);
        }
        public void IsMethodEqualToBaseTypeMethod()
        {
            var moduleScopeStub = MockRepository.GenerateStub <ModuleScope> ();

            var baseType    = typeof(ProxiedChildGeneric <int, string>);
            var proxiedType = typeof(ProxiedChildChildGeneric <int, string>);

            var typeFilter = new TypeLevelTypeFilter(new[] { baseType });
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, moduleScopeStub);

            var methodFromBaseType = ScriptingHelper.GetInstanceMethod(baseType, "ProxiedChildGenericToString", new[] { typeof(int), typeof(string) });
            var method             = ScriptingHelper.GetInstanceMethod(proxiedType, "ProxiedChildGenericToString", new[] { typeof(int), typeof(string) });

            Assert.That(methodFromBaseType, Is.Not.EqualTo(method));

            // Shows methodInfo.GetBaseDefinition()-bug: Results should be equal.
            Assert.That(methodFromBaseType.GetBaseDefinition(), Is.Not.EqualTo(method.GetBaseDefinition()));

            Assert.That(methodFromBaseType.ReflectedType, Is.EqualTo(baseType));

            Assert.That(stableBindingProxyBuilder.IsMethodEqualToBaseTypeMethod(method, method), Is.True);
            Assert.That(stableBindingProxyBuilder.IsMethodEqualToBaseTypeMethod(method, methodFromBaseType), Is.True);

            var sumMethod = proxiedType.GetMethod("Sum", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            Assert.That(stableBindingProxyBuilder.IsMethodEqualToBaseTypeMethod(sumMethod, methodFromBaseType), Is.False);
        }
        public void BuildClassMethodToInterfaceMethodsMap_TwoInterfaceMethodsImplementedAsOnePublicMethod()
        {
            var typeIProcessText1 = typeof(IProcessText1);
            var typeIProcessText2 = typeof(IProcessText2);
            var typeFilter        = new TypeLevelTypeFilter(new[] { typeIProcessText2, typeof(Proxied), typeIProcessText1 });
            // Note: ProxiedChildChild implements IProcessText1 and IProcessText2 through one public member
            var proxiedType = typeof(ProxiedChildChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildClassMethodToInterfaceMethodsMap_TwoInterfaceMethodsImplementedAsOnePublicMethod"));

            var classMethodToInterfaceMethodsMap = stableBindingProxyBuilder.GetClassMethodToInterfaceMethodsMap();

            var stringTimesIProcessText1ClassMethod = GetAnyInstanceMethod(proxiedType, "ProcessText");

            Assert.That(stringTimesIProcessText1ClassMethod, Is.Not.Null);

            var stringTimesIProcessText1InterfaceMethod = GetAnyInstanceMethod(typeIProcessText1, "ProcessText");

            Assert.That(stringTimesIProcessText1InterfaceMethod, Is.Not.Null);
            var stringTimesIProcessText2InterfaceMethod = GetAnyInstanceMethod(typeIProcessText2, "ProcessText");

            Assert.That(stringTimesIProcessText2InterfaceMethod, Is.Not.Null);

            Assert.That(classMethodToInterfaceMethodsMap.Count, Is.EqualTo(1));
            Assert.That(classMethodToInterfaceMethodsMap[stringTimesIProcessText1ClassMethod].ToList(), Is.EquivalentTo(ListObjectMother.New(stringTimesIProcessText1InterfaceMethod, stringTimesIProcessText2InterfaceMethod)));
        }
        public void BuildProxyType_PublicProperty_WithSetter()
        {
            var knownBaseTypes            = new[] { typeof(ProxiedChild) };
            var knownTypes                = knownBaseTypes; //knownBaseTypes.Union (knownInterfaceTypes).ToArray ();
            var typeFilter                = new TypeLevelTypeFilter(knownTypes);
            var proxiedType               = typeof(ProxiedChildChildChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_PublicProperty"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            // Create proxy instance, initializing it with class to be proxied
            var    proxied = new ProxiedChildChildChild("PC");
            object proxy   = Activator.CreateInstance(proxyType, proxied);

            Assert.That(proxied.NameProperty, Is.EqualTo("ProxiedChildChildChild::NameProperty PC"));

            //To.ConsoleLine.e ("proxyType.GetAllProperties()", proxyType.GetAllProperties ()).nl ().e (proxyType.GetAllProperties ().Select (pi => pi.Attributes)).nl (2).e ("proxyType.GetAllMethods()", proxyType.GetAllMethods ());

            var proxyPropertyInfo = proxyType.GetProperty("NameProperty", _publicInstanceFlags);

            Assert.That(proxyPropertyInfo, Is.Not.Null);
            Assert.That(proxyPropertyInfo.CanRead, Is.True);
            Assert.That(proxyPropertyInfo.CanWrite, Is.True);
            Assert.That(proxyPropertyInfo.GetValue(proxy, null), Is.EqualTo("ProxiedChild::NameProperty PC"));

            proxyPropertyInfo.SetValue(proxy, "XXyyZZ", null);
            Assert.That(proxyPropertyInfo.GetValue(proxy, null), Is.EqualTo("ProxiedChild::NameProperty XXyyZZ-ProxiedChild::NameProperty"));
        }
        public void BuildClassMethodToInterfaceMethodsMap_TwoExplicitInterfaceMethods()
        {
            var typeIAmbigous1 = typeof(IAmbigous1);
            var typeIAmbigous2 = typeof(IAmbigous2);
            var typeFilter     = new TypeLevelTypeFilter(new[] { typeIAmbigous2, typeof(Proxied), typeIAmbigous1 });
            // Note: ProxiedChild implements IAmbigous1 and IAmbigous2
            var proxiedType = typeof(ProxiedChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildClassMethodToInterfaceMethodsMap_TwoExplicitInterfaceMethods"));

            var classMethodToInterfaceMethodsMap = stableBindingProxyBuilder.GetClassMethodToInterfaceMethodsMap();

            var stringTimesIAmbigous1ClassMethod = GetAnyInstanceMethod(proxiedType, "Remotion.Scripting.UnitTests.TestDomain.IAmbigous1.StringTimes");

            Assert.That(stringTimesIAmbigous1ClassMethod, Is.Not.Null);
            var stringTimesIAmbigous1InterfaceMethod = GetAnyInstanceMethod(typeIAmbigous1, "StringTimes");

            Assert.That(stringTimesIAmbigous1InterfaceMethod, Is.Not.Null);

            var stringTimesIAmbigous2ClassMethod = GetAnyInstanceMethod(proxiedType, "Remotion.Scripting.UnitTests.TestDomain.IAmbigous2.StringTimes");

            Assert.That(stringTimesIAmbigous2ClassMethod, Is.Not.Null);
            var stringTimesIAmbigous2InterfaceMethod = GetAnyInstanceMethod(typeIAmbigous2, "StringTimes");

            Assert.That(stringTimesIAmbigous2InterfaceMethod, Is.Not.Null);

            Assert.That(classMethodToInterfaceMethodsMap.Count, Is.EqualTo(2));
            Assert.That(classMethodToInterfaceMethodsMap[stringTimesIAmbigous1ClassMethod].ToList(), Is.EquivalentTo(ListObjectMother.New(stringTimesIAmbigous1InterfaceMethod)));
            Assert.That(classMethodToInterfaceMethodsMap[stringTimesIAmbigous2ClassMethod].ToList(), Is.EquivalentTo(ListObjectMother.New(stringTimesIAmbigous2InterfaceMethod)));
        }
        private void Assert_BuildProxyType_MultipleKnownInterfaces_PublicAndExplicitInterfaceImplementation(
            Type[] knownBaseTypes, Type[] knownInterfaceTypes, Type proxiedType)
        {
            var knownTypes = knownBaseTypes.Union(knownInterfaceTypes).ToArray();
            var typeFilter = new TypeLevelTypeFilter(knownTypes);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_MultipleKnownInterfaces_PublicAndExplicitInterfaceImplementation"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            var knownBaseTypeMethods = knownBaseTypes.SelectMany(t => t.GetMethods()).Where(m => m.IsSpecialName == false);
            var proxyMethods         = proxyType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(m => m.IsSpecialName == false && m.DeclaringType != typeof(Object));
            var interfaceMethods     = knownInterfaceTypes.SelectMany(t => t.GetMethods(BindingFlags.Instance | BindingFlags.Public));

            //To.ConsoleLine.e (knownBaseTypeMethods).nl (3).e (interfaceMethods).nl (3).e (proxyMethods).nl (3);

            Assert.That(knownBaseTypeMethods.Count() + interfaceMethods.Count() + typeof(IProxy).GetMethods().Length, // + typeof (IProxy).GetMethods ().Length,
                        Is.EqualTo(proxyMethods.Count()));

            AssertHasSameExplicitInterfaceMethod(typeof(IAmbigous3), proxiedType, proxyType, "StringTimes2", typeof(String), typeof(Int32));
            AssertHasSameExplicitInterfaceMethod(typeof(IAmbigous4), proxiedType, proxyType, "StringTimes2", typeof(String), typeof(Int32));
            AssertHasSameMethod(typeof(ProxiedChild), proxyType, "StringTimes2", typeof(String), typeof(Int32));

            AssertHasSameExplicitInterfaceMethod(typeof(IAmbigous3), proxiedType, proxyType, "AnotherMethod", typeof(String), typeof(Int32));
            AssertHasSameExplicitInterfaceMethod(typeof(IAmbigous4), proxiedType, proxyType, "AnotherMethod", typeof(String), typeof(Int32));
            AssertHasSameMethod(typeof(ProxiedChild), proxyType, "AnotherMethod", typeof(String), typeof(Int32));

            AssertHasSameExplicitInterfaceMethod(typeof(IAmbigous1), proxiedType, proxyType, "StringTimes", typeof(String), typeof(Int32));
            AssertHasSameExplicitInterfaceMethod(typeof(IAmbigous2), proxiedType, proxyType, "StringTimes", typeof(String), typeof(Int32));
        }
        public void Ctor()
        {
            var typeFilter  = new TypeLevelTypeFilter(new Type[0]);
            var proxiedType = typeof(string);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("Ctor"));

            Assert.That(stableBindingProxyBuilder.ProxiedType, Is.EqualTo(proxiedType));
            Assert.That(stableBindingProxyBuilder.GetTypeFilter(), Is.EqualTo(typeFilter));
        }
        public void BuildProxyType_NoKnownBaseType()
        {
            var typeFilter  = new TypeLevelTypeFilter(new[] { typeof(IAmbigous1) });
            var proxiedType = typeof(ProxiedChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_NoKnownBaseType"));

            // Having no known base type must not throw
            stableBindingProxyBuilder.BuildProxyType();
        }
        public void BuildProxyType_NoKnownBaseTypeAndNoKnownInterfaces()
        {
            var typeFilter  = new TypeLevelTypeFilter(new Type[0]);
            var proxiedType = typeof(ProxiedChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_NoKnownBaseType"));

            // Having no known base type and no known interfaces must not throw
            stableBindingProxyBuilder.BuildProxyType();
        }
        public void ParamsCtor()
        {
            var typeFilter = new TypeLevelTypeFilter(typeof(string), this.GetType());

            Assert.That(typeFilter.IsTypeValid(typeof(string)), Is.True);
            Assert.That(typeFilter.IsTypeValid(typeof(TypeLevelTypeFilterTest)), Is.True);

            Assert.That(typeFilter.IsTypeValid(typeof(TypeLevelTypeFilter)), Is.False);
            Assert.That(typeFilter.IsTypeValid(typeof(object)), Is.False);
        }
        public void BuildProxyType_AmbigousExplicitInterfaceProperties_With_PublicInterfaceImplementation()
        {
            var knownBaseTypes            = new[] { typeof(ProxiedChildChild) };
            var knownInterfaceTypes       = new[] { typeof(IProperty), typeof(IPropertyAmbigous2) };
            var knownTypes                = knownBaseTypes.Union(knownInterfaceTypes).ToArray();
            var typeFilter                = new TypeLevelTypeFilter(knownTypes);
            var proxiedType               = typeof(ProxiedChildChildChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_ExplicitInterfaceProperty"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            Assert.That(proxyType.GetInterface("IPropertyAmbigous2"), Is.Not.Null);
            Assert.That(proxyType.GetInterface("IPropertyAmbigous1"), Is.Null);

            // Create proxy instance, initializing it with class to be proxied
            var proxied = new ProxiedChildChildChild("PC");

            object proxy = Activator.CreateInstance(proxyType, proxied);

            const string expectedPropertyValue = "ProxiedChildChild::IPropertyAmbigous2::PropertyAmbigous PC";

            Assert.That(((IPropertyAmbigous2)proxied).PropertyAmbigous, Is.EqualTo(expectedPropertyValue));

            //To.ConsoleLine.e ("proxyType.GetAllProperties()", proxyType.GetAllProperties ()).nl ().e (proxyType.GetAllProperties ().Select(pi => pi.Attributes)).nl (2).e ("proxyType.GetAllMethods()", proxyType.GetAllMethods ());


            var proxyPropertyInfoPublicProperty = proxyType.GetProperty("PropertyAmbigous", _publicInstanceFlags);

            Assert.That(proxyPropertyInfoPublicProperty, Is.Not.Null);

            Assert.That(ScriptingHelper.ExecuteScriptExpression <string> ("p0.PropertyAmbigous", proxy), Is.EqualTo("ProxiedChildChild::PropertyAmbigous PC"));

            var proxyPropertyInfo = proxyType.GetProperty(
                "Remotion.Scripting.UnitTests.TestDomain.ProxiedChild.Remotion.Scripting.UnitTests.TestDomain.IPropertyAmbigous2.PropertyAmbigous", _nonPublicInstanceFlags);

            Assert.That(proxyPropertyInfo, Is.Not.Null);
            Assert.That(proxyPropertyInfo.GetValue(proxy, null), Is.EqualTo(expectedPropertyValue));
            //AssertPropertyInfoEqual (proxyPropertyInfo, propertyInfo);

            ((IPropertyAmbigous2)proxied).PropertyAmbigous = "aBc";
            const string expectedPropertyValue2 = "ProxiedChildChild::IPropertyAmbigous2::PropertyAmbigous aBc-ProxiedChildChild::IPropertyAmbigous2::PropertyAmbigous";

            Assert.That(((IPropertyAmbigous2)proxied).PropertyAmbigous, Is.EqualTo(expectedPropertyValue2));
            Assert.That(proxyPropertyInfo.GetValue(proxy, null), Is.EqualTo(expectedPropertyValue2));

            proxyPropertyInfo.SetValue(proxy, "XXyyZZ", null);
            const string expectedPropertyValue3 = "ProxiedChildChild::IPropertyAmbigous2::PropertyAmbigous XXyyZZ-ProxiedChildChild::IPropertyAmbigous2::PropertyAmbigous";

            Assert.That(((IPropertyAmbigous2)proxied).PropertyAmbigous, Is.EqualTo(expectedPropertyValue3));
            Assert.That(proxyPropertyInfo.GetValue(proxy, null), Is.EqualTo(expectedPropertyValue3));

            var proxyPropertyInfo2 = proxyType.GetProperty(
                "Remotion.Scripting.UnitTests.TestDomain.ProxiedChild.Remotion.Scripting.UnitTests.TestDomain.IPropertyAmbigous1.PropertyAmbigous", _nonPublicInstanceFlags);

            Assert.That(proxyPropertyInfo2, Is.Null);
        }
        private void AssertBuildProxyType_MethodHiddenWithNew(Type knownBaseType, Type proxiedType, bool expectProxiedCallDifferent, string methodName)
        {
            var typeFilter = new TypeLevelTypeFilter(new[] { knownBaseType });
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("AssertBuildProxyType_MethodHiddenWithNew"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            var          proxiedTypeInstance = Activator.CreateInstance(proxiedType, "Peter");
            var          proxy    = Activator.CreateInstance(proxyType, proxiedTypeInstance);
            const string argument = "Fox";

            // Test that call to proxy method is not ambigous
            PrivateInvoke.InvokePublicMethod(proxy, methodName, argument);
        }
        public void GetInterfaceMethodsToClassMethod()
        {
            var typeIAmbigous2            = typeof(IAmbigous2);
            var typeFilter                = new TypeLevelTypeFilter(new[] { typeIAmbigous2 });
            var proxiedType               = typeof(ProxiedChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("GetInterfaceMethodsToClassMethod"));

            var stringTimesIAmbigous1ClassMethod     = GetAnyInstanceMethod(proxiedType, "Remotion.Scripting.UnitTests.TestDomain.IAmbigous1.StringTimes");
            var stringTimesIAmbigous2ClassMethod     = GetAnyInstanceMethod(proxiedType, "Remotion.Scripting.UnitTests.TestDomain.IAmbigous2.StringTimes");
            var stringTimesIAmbigous2InterfaceMethod = GetAnyInstanceMethod(typeIAmbigous2, "StringTimes");

            Assert.That(stableBindingProxyBuilder.GetInterfaceMethodsToClassMethod(stringTimesIAmbigous1ClassMethod).ToList(), Is.Empty);
            Assert.That(stableBindingProxyBuilder.GetInterfaceMethodsToClassMethod(stringTimesIAmbigous2ClassMethod).ToList(), Is.EquivalentTo(ListObjectMother.New(stringTimesIAmbigous2InterfaceMethod)));
        }
Ejemplo n.º 17
0
        public void BuildProxyType()
        {
            var typeFilter = new TypeLevelTypeFilter(new[] { typeof(ProxiedChild) });
            var provider   = new StableBindingProxyProvider(
                typeFilter, CreateModuleScope("GetTypeMemberProxy"));

            Assert.That(provider.TypeFilter, Is.SameAs(typeFilter));

            var          proxied       = new ProxiedChildChildChild("abrakadava");
            const string attributeName = "PrependName";

            var proxyType = provider.BuildProxyType(proxied.GetType());

            var proxyMethod = proxyType.GetAllInstanceMethods(attributeName, typeof(string)).Single();

            Assert.That(proxyMethod, Is.Not.Null);
        }
        public void BuildProxyType_ObjectMethods()
        {
            var knownBaseType             = typeof(Proxied);
            var typeFilter                = new TypeLevelTypeFilter(new[] { knownBaseType });
            var proxiedType               = typeof(ProxiedChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_ObjectMethods"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            var proxied = new ProxiedChild();
            var proxy   = Activator.CreateInstance(proxyType, proxied);

            Assert.That(InvokeMethod(proxy, "ToString"), Is.EqualTo(proxied.ToString()));
            Assert.That(InvokeMethod(proxy, "GetType"), Is.EqualTo(proxied.GetType()));
            Assert.That(InvokeMethod(proxy, "GetHashCode"), Is.EqualTo(proxied.GetHashCode()));
            Assert.That(InvokeMethod(proxy, "Equals", proxied), Is.True);
            Assert.That(InvokeMethod(proxy, "Equals", proxy), Is.False);
        }
        private void AssertBuildProxyType_MethodOverridden(Type knownBaseType, Type proxiedType, string methodName, bool expectKnownBaseTypeCallDifferent)
        {
            var typeFilter = new TypeLevelTypeFilter(new[] { knownBaseType });
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("AssertBuildProxyType_MethodOverridden_ProxiedTypeIsKnownBaseType"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            var          proxiedTypeInstance   = Activator.CreateInstance(proxiedType, "Peter");
            var          knownBaseTypeInstance = Activator.CreateInstance(knownBaseType, "Peter");
            var          proxy    = Activator.CreateInstance(proxyType, proxiedTypeInstance);
            const string argument = "Fox";

            var proxyResult = InvokeMethod(proxy, methodName, argument);

            // We expect the call to be virtual.
            Assert.That(proxyResult, Is.EqualTo(InvokeMethod(proxiedTypeInstance, methodName, argument)));
            if (expectKnownBaseTypeCallDifferent)
            {
                Assert.That(proxyResult, Is.Not.EqualTo(InvokeMethod(knownBaseTypeInstance, methodName, argument)));
            }
        }
        public void BuildProxyType_PublicProperty()
        {
            var knownBaseTypes            = new[] { typeof(ProxiedChildChild) };
            var knownTypes                = knownBaseTypes; //knownBaseTypes.Union (knownInterfaceTypes).ToArray ();
            var typeFilter                = new TypeLevelTypeFilter(knownTypes);
            var proxiedType               = typeof(ProxiedChildChildChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_PublicProperty"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            // Create proxy instance, initializing it with class to be proxied
            var    proxied = new ProxiedChildChildChild("PC");
            object proxy   = Activator.CreateInstance(proxyType, proxied);

            Assert.That(proxied.NameProperty, Is.EqualTo("ProxiedChildChildChild::NameProperty PC"));

            var proxyPropertyInfo = proxyType.GetProperty("NameProperty", _publicInstanceFlags);

            Assert.That(proxyPropertyInfo, Is.Not.Null);
            Assert.That(proxyPropertyInfo.CanRead, Is.True);
            Assert.That(proxyPropertyInfo.CanWrite, Is.False);
            Assert.That(proxyPropertyInfo.GetValue(proxy, null), Is.EqualTo("ProxiedChildChild::NameProperty PC"));
        }
        public void BuildProxyType_CheckMembers()
        {
            var knownBaseType             = typeof(Proxied);
            var typeFilter                = new TypeLevelTypeFilter(new[] { knownBaseType });
            var proxiedType               = typeof(ProxiedChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            var knownBaseTypeMethods = knownBaseType.GetMethods().Where(m => m.IsSpecialName == false);
            var proxyMethods         = proxyType.GetMethods().Where(m => m.IsSpecialName == false && m.DeclaringType != typeof(Object));

            Assert.That(knownBaseTypeMethods.Count(), Is.EqualTo(proxyMethods.Count()));

            AssertHasSameMethod(knownBaseType, proxyType, "GetName");
            AssertHasSameMethod(knownBaseType, proxyType, "Sum", typeof(Int32[]));
            AssertHasSameMethod(knownBaseType, proxyType, "PrependName", typeof(String));
            AssertHasSameMethod(knownBaseType, proxyType, "SumMe", typeof(Int32[]));

            AssertHasSameMethod(knownBaseType, proxyType, "OverrideMe", typeof(String));

            AssertHasSameGenericMethod(knownBaseType, proxyType, "GenericToString", 2);
            AssertHasSameGenericMethod(knownBaseType, proxyType, "OverloadedGenericToString", 1);
            AssertHasSameGenericMethod(knownBaseType, proxyType, "OverloadedGenericToString", 2);
        }
        public void BuildProxyType_CheckInterfaceMembers()
        {
            var knownBaseType             = typeof(Proxied);
            var knownInterfaceType        = typeof(IAmbigous2);
            var typeFilter                = new TypeLevelTypeFilter(new[] { knownBaseType, knownInterfaceType });
            var proxiedType               = typeof(ProxiedChild);
            var stableBindingProxyBuilder = new StableBindingProxyBuilder(proxiedType, typeFilter, CreateModuleScope("BuildProxyType_CheckInterfaceMembers"));
            var proxyType = stableBindingProxyBuilder.BuildProxyType();

            var knownBaseTypeMethods = knownBaseType.GetMethods().Where(m => m.IsSpecialName == false);
            var proxyMethods         = proxyType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(m => m.IsSpecialName == false && m.DeclaringType != typeof(Object));
            var interfaceMethods     = knownInterfaceType.GetMethods(BindingFlags.Instance | BindingFlags.Public);

            //To.ConsoleLine.e (knownBaseTypeMethods).nl (3).e (proxyMethods).nl (4);
            //To.ConsoleLine.e (knownInterfaceType.GetMethods()).nl (3).e (interfaceProxyMethods).nl (3);

            Assert.That(knownBaseTypeMethods.Count() + interfaceMethods.Count() + typeof(IProxy).GetMethods().Length, Is.EqualTo(proxyMethods.Count()));

            //---------------------------------------------------------------------------------------------------------------------------------
            // Adding IAmbigous2 interface adds StringTimes(string,int) explicit interface implementation.
            // Note: StringTimes(string,int) exists 3x in ProxiedChild, as a regular member and as an explicit interface implementation from
            // IAmbigous1 and IAmbigous2. Since the first is private and the second is not known, only the StringTimes coming from
            // IAmbigous2 is exposed.
            //---------------------------------------------------------------------------------------------------------------------------------
            AssertHasSameExplicitInterfaceMethod(knownInterfaceType, proxiedType, proxyType, "StringTimes", typeof(String), typeof(Int32));

            // Methods coming from knownBaseType Proxied are still here:
            AssertHasSameMethod(knownBaseType, proxyType, "GetName");
            AssertHasSameMethod(knownBaseType, proxyType, "Sum", typeof(Int32[]));
            AssertHasSameMethod(knownBaseType, proxyType, "PrependName", typeof(String));
            AssertHasSameMethod(knownBaseType, proxyType, "SumMe", typeof(Int32[]));
            AssertHasSameMethod(knownBaseType, proxyType, "OverrideMe", typeof(String));
            AssertHasSameGenericMethod(knownBaseType, proxyType, "GenericToString", 2);
            AssertHasSameGenericMethod(knownBaseType, proxyType, "OverloadedGenericToString", 1);
            AssertHasSameGenericMethod(knownBaseType, proxyType, "OverloadedGenericToString", 2);
        }