コード例 #1
0
        protected MethodBaseBodyContextBase(MutableType declaringType, bool isStatic, IEnumerable <ParameterExpression> parameterExpressions)
            : base(declaringType, isStatic)
        {
            ArgumentUtility.CheckNotNull("parameterExpressions", parameterExpressions);

            _parameters = parameterExpressions.ToList().AsReadOnly();
        }
コード例 #2
0
        public void ModifyTargetType(
            MutableType concreteTarget,
            TargetClassDefinition targetClassDefinition,
            IEnumerable <Type> interfacesToImplement,
            IList <IMixinInfo> mixinInfos)
        {
            ArgumentUtility.CheckNotNull("concreteTarget", concreteTarget);
            ArgumentUtility.CheckNotNull("targetClassDefinition", targetClassDefinition);
            ArgumentUtility.CheckNotNull("interfacesToImplement", interfacesToImplement);
            ArgumentUtility.CheckNotNull("mixinInfos", mixinInfos);

            var targetTypeGenerator = new TargetTypeGenerator(concreteTarget, new ExpressionBuilder(), new AttributeGenerator(), _nextCallProxyGenerator);
            var mixinTypes          = mixinInfos.Select(t => t.MixinType).ToList();

            targetTypeGenerator.AddInterfaces(interfacesToImplement);
            targetTypeGenerator.AddExtensionsField();
            targetTypeGenerator.AddNextCallProxy(targetClassDefinition, mixinInfos);
            targetTypeGenerator.AddFields();
            targetTypeGenerator.AddTypeInitializations(targetClassDefinition.ConfigurationContext, mixinTypes);
            targetTypeGenerator.AddInitializations(mixinTypes);

            targetTypeGenerator.ImplementIMixinTarget(targetClassDefinition.Name);
            targetTypeGenerator.ImplementIntroducedInterfaces(targetClassDefinition.ReceivedInterfaces);
            targetTypeGenerator.ImplementRequiredDuckMethods(targetClassDefinition);
            targetTypeGenerator.ImplementAttributes(targetClassDefinition);

            targetTypeGenerator.AddMixedTypeAttribute(targetClassDefinition);
            targetTypeGenerator.AddDebuggerDisplayAttribute(targetClassDefinition);

            targetTypeGenerator.ImplementOverrides(targetClassDefinition);
            targetTypeGenerator.ImplementOverridingMethods(targetClassDefinition, mixinInfos);
        }
コード例 #3
0
 /// <summary>
 /// Adds the default control states for a set of controls.
 /// </summary>
 /// <param name="ids">
 /// List of control identifiers
 /// </param>
 /// <param name="mutable">
 /// Mutability of controls. Applies to all controls in list.
 /// </param>
 private void AddControlDefaultStatesMultiple(List <string> ids, MutableType mutable)
 {
     foreach (string id in ids)
     {
         AddControlDefaultStates(id, mutable);
     }
 }
コード例 #4
0
        public void ModifyType(MutableType mutableType)
        {
            var typeAspects = _declarationProvider.GetDeclarations(mutableType).ConvertToCollection();

            typeAspects.ForEach(x => _intertypeWeaver.Import(x, new JoinPoint(mutableType)));

            foreach (var event_ in mutableType.UnderlyingSystemType.GetEvents().Where(x => x.GetAddMethod().IsVirtual))
            {
                _eventMethodPreparer.Prepare(mutableType, event_);
            }

            foreach (var method in mutableType.AllMutableMethods.ToArray())
            {
                //method.SetBody (ctx => new MethodExecutionExpression (method));
                //continue;
                // TODO: remove UnderlyingSystemMethodInfo
                var methodAspects = _declarationProvider.GetDeclarations(method.UnderlyingSystemMethodInfo).ConvertToCollection();
                var allAspects    = typeAspects.Concat(methodAspects).ConvertToCollection();

                var joinPoint  = new JoinPoint(method, new MethodExecutionExpression(method));
                var allAdvices = _adviceComposer.Compose(allAspects, joinPoint).ToList();

                if (allAdvices.Any())
                {
                    _adviceWeaver.Weave(joinPoint, allAdvices);
                }
            }
        }
コード例 #5
0
        public InitializationBodyContext(MutableType declaringType, bool isStatic, ParameterExpression initializationSemantics)
            : base(declaringType, isStatic)
        {
            ArgumentUtility.CheckNotNull("initializationSemantics", initializationSemantics);

            _initializationSemantics = initializationSemantics;
        }
コード例 #6
0
        public INextCallProxy Create(
            MutableType concreteTarget,
            FieldInfo extensionsField,
            TargetClassDefinition targetClassDefinition,
            IList <IMixinInfo> mixinInfos)
        {
            ArgumentUtility.CheckNotNull("concreteTarget", concreteTarget);
            ArgumentUtility.CheckNotNull("targetClassDefinition", targetClassDefinition);
            ArgumentUtility.CheckNotNull("mixinInfos", mixinInfos);

            var nextCallProxyType = CreateNextCallProxyType(concreteTarget, targetClassDefinition);

            var thisField  = AddPublicField(nextCallProxyType, "__this", concreteTarget);
            var depthField = AddPublicField(nextCallProxyType, "__depth", typeof(int));

            var constructor = AddConstructor(nextCallProxyType, concreteTarget, thisField, depthField);

            var targetTypeForNextCall   = GetTargetTypeWrapper(concreteTarget, extensionsField);
            var nextCallMethodGenerator = new NextCallMethodGenerator(
                targetClassDefinition, targetTypeForNextCall, thisField, depthField, mixinInfos);
            var nextCallProxy = new NextCallProxy(nextCallProxyType, constructor, targetClassDefinition, nextCallMethodGenerator);

            nextCallProxy.ImplementBaseCallsForOverriddenMethodsOnTarget();
            nextCallProxy.ImplementBaseCallsForRequirements();

            return(nextCallProxy);
        }
コード例 #7
0
        public virtual void SetUp()
        {
            _mockRepository = new MockRepository();

            _mutableType = MutableTypeObjectMother.Create();
            _nestedTypeCodeGeneratorFactoryMock = _mockRepository.StrictMock <IMutableNestedTypeCodeGeneratorFactory>();
            _codeGeneratorMock             = _mockRepository.StrictMock <IReflectionEmitCodeGenerator>();
            _emittableOperandProviderMock  = _mockRepository.StrictMock <IEmittableOperandProvider> ();
            _memberEmitterMock             = _mockRepository.StrictMock <IMemberEmitter>();
            _initializationBuilderMock     = _mockRepository.StrictMock <IInitializationBuilder>();
            _proxySerializationEnablerMock = _mockRepository.StrictMock <IProxySerializationEnabler>();

            _generator = new MutableTypeCodeGenerator(
                _mutableType,
                _nestedTypeCodeGeneratorFactoryMock,
                _codeGeneratorMock,
                _emittableOperandProviderMock,
                _memberEmitterMock,
                _initializationBuilderMock,
                _proxySerializationEnablerMock);

            _typeBuilderMock        = _mockRepository.StrictMock <ITypeBuilder>();
            _debugInfoGeneratorMock = _mockRepository.StrictMock <DebugInfoGenerator>();

            _fakeInitializationField   = ReflectionObjectMother.GetSomeField();
            _fakeInitializationMethod  = ReflectionObjectMother.GetSomeMethod();
            _fakeInitializationMembers = Tuple.Create(_fakeInitializationField, _fakeInitializationMethod);
        }
コード例 #8
0
        public MutableConstructorInfo CreateConstructor(
            MutableType declaringType,
            MethodAttributes attributes,
            IEnumerable <ParameterDeclaration> parameters,
            Func <ConstructorBodyCreationContext, Expression> bodyProvider)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNull("parameters", parameters);
            ArgumentUtility.CheckNotNull("bodyProvider", bodyProvider);

            MemberAttributesUtility.ValidateAttributes("constructors", MemberAttributesUtility.InvalidConstructorAttributes, attributes, "attributes");

            var isStatic = attributes.IsSet(MethodAttributes.Static);
            var paras    = parameters.ToList();

            if (isStatic && paras.Count != 0)
            {
                throw new ArgumentException("A type initializer (static constructor) cannot have parameters.", "parameters");
            }

            var signature = new MethodSignature(typeof(void), paras.Select(p => p.Type), 0);

            if (declaringType.AddedConstructors.Any(ctor => ctor.IsStatic == isStatic && MethodSignature.Create(ctor).Equals(signature)))
            {
                throw new InvalidOperationException("Constructor with equal signature already exists.");
            }

            var parameterExpressions = paras.Select(p => p.Expression);
            var context = new ConstructorBodyCreationContext(declaringType, isStatic, parameterExpressions);
            var body    = BodyProviderUtility.GetTypedBody(typeof(void), bodyProvider, context);

            var attr = attributes.Set(MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

            return(new MutableConstructorInfo(declaringType, attr, paras, body));
        }
コード例 #9
0
        public void SetUp()
        {
            _declaringType = MutableTypeObjectMother.Create();
            _isStatic      = BooleanObjectMother.GetRandomBoolean();

            _context = new TestableMethodBaseBodyContextBase(_declaringType, new ParameterExpression[0], _isStatic);
        }
コード例 #10
0
        public void MakeSerializable(MutableType proxyType, MethodInfo initializationMethod)
        {
            ArgumentUtility.CheckNotNull("proxyType", proxyType);
            // initializationMethod may be null

            // Base fields are always serialized by the standard .NET serialization or by an implementation of ISerializable on the base type.
            // Added fields are also serialized by the standard .NET serialization, unless the proxy type implements ISerializable. In that case,
            // we need to extend the ISerializable implementation to include the added fields.

            var serializedFieldMapping     = _serializableFieldFinder.GetSerializableFieldMapping(proxyType.AddedFields.Cast <FieldInfo>()).ToArray();
            var deserializationConstructor = GetDeserializationConstructor(proxyType);

            // If the base type implements ISerializable but has no deserialization constructor, we can't implement ISerializable correctly, so
            // we don't even try. (ComplexSerializationEnabler relies on this behavior.)
            var needsCustomFieldSerialization =
                serializedFieldMapping.Length != 0 && typeof(ISerializable).IsTypePipeAssignableFrom(proxyType) && deserializationConstructor != null;

            if (needsCustomFieldSerialization)
            {
                OverrideGetObjectData(proxyType, serializedFieldMapping);
                AdaptDeserializationConstructor(deserializationConstructor, serializedFieldMapping);
            }

            if (initializationMethod != null)
            {
                if (typeof(IDeserializationCallback).IsTypePipeAssignableFrom(proxyType))
                {
                    OverrideOnDeserialization(proxyType, initializationMethod);
                }
                else if (proxyType.IsTypePipeSerializable())
                {
                    ExplicitlyImplementOnDeserialization(proxyType, initializationMethod);
                }
            }
        }
コード例 #11
0
        private void OverrideGetObjectData(MutableType proxyType, Tuple <string, FieldInfo>[] serializedFieldMapping)
        {
            try
            {
                proxyType
                .GetOrAddImplementation(s_getObjectDataMethod)
                .SetBody(
                    ctx => Expression.Block(
                        typeof(void),
                        new[] { ctx.PreviousBody }.Concat(BuildFieldSerializationExpressions(ctx.This, ctx.Parameters[0], serializedFieldMapping))));
            }
            catch (NotSupportedException)
            {
                // Overriding and re-implementation failed because the base implementation is not accessible from the proxy.
                // Do nothing here; error reporting code will be generated in the ProxySerializationEnabler.
                // Add an explicit re-implementation that throws exception (instead of simply throwing an exception here).
                // Reasoning: Users often cannot influence the requested type and do not care about any serialization problem.

                proxyType.AddInterface(typeof(ISerializable), throwIfAlreadyImplemented: false);

                var message = "The requested type implements ISerializable but GetObjectData is not accessible from the proxy. "
                              + "Make sure that GetObjectData is implemented implicitly (not explicitly).";
                proxyType.AddExplicitOverride(
                    s_getObjectDataMethod,
                    ctx => Expression.Throw(Expression.New(s_serializationExceptionConstructor, Expression.Constant(message))));
            }
        }
コード例 #12
0
        private void OverrideOnDeserialization(MutableType proxyType, MethodInfo initializationMethod)
        {
            try
            {
                proxyType.GetOrAddImplementation(s_onDeserializationMethod)
                .SetBody(
                    ctx => Expression.Block(
                        typeof(void),
                        ctx.PreviousBody,
                        CallInitializationMethod(ctx.This, initializationMethod)));
            }
            catch (NotSupportedException)
            {
                // Overriding and re-implementation failed because the base implementation is not accessible from the proxy.
                // Add an explicit re-implementation that throws exception (instead of simply throwing an exception here).
                // Reasoning: Users often cannot influence the requested type and do not care about any serialization problem.

                proxyType.AddInterface(typeof(IDeserializationCallback), throwIfAlreadyImplemented: false);

                var message = "The requested type implements IDeserializationCallback but OnDeserialization is not accessible from the proxy. "
                              + "Make sure that OnDeserialization is implemented implicitly (not explicitly).";
                proxyType.AddExplicitOverride(
                    s_onDeserializationMethod,
                    ctx => Expression.Throw(Expression.New(s_serializationExceptionConstructor, Expression.Constant(message))));
            }
        }
コード例 #13
0
        private MutableConstructorInfo GetDeserializationConstructor(MutableType type)
        {
            var parameterTypes = new[] { typeof(SerializationInfo), typeof(StreamingContext) };

            return(type.AddedConstructors
                   .SingleOrDefault(c => !c.IsStatic && c.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes)));
        }
コード例 #14
0
        public MutableTypeCodeGenerator(
            MutableType mutableType,
            IMutableNestedTypeCodeGeneratorFactory nestedTypeCodeGeneratorFactory,
            IReflectionEmitCodeGenerator codeGenerator,
            IEmittableOperandProvider emittableOperandProvider,
            IMemberEmitter memberEmitter,
            IInitializationBuilder initializationBuilder,
            IProxySerializationEnabler proxySerializationEnabler)
        {
            ArgumentUtility.CheckNotNull("mutableType", mutableType);
            ArgumentUtility.CheckNotNull("nestedTypeCodeGeneratorFactory", nestedTypeCodeGeneratorFactory);
            ArgumentUtility.CheckNotNull("codeGenerator", codeGenerator);
            ArgumentUtility.CheckNotNull("emittableOperandProvider", emittableOperandProvider);
            ArgumentUtility.CheckNotNull("memberEmitter", memberEmitter);
            ArgumentUtility.CheckNotNull("initializationBuilder", initializationBuilder);
            ArgumentUtility.CheckNotNull("proxySerializationEnabler", proxySerializationEnabler);

            _mutableType = mutableType;
            _nestedTypeCodeGeneratorFactory = nestedTypeCodeGeneratorFactory;
            _codeGenerator             = codeGenerator;
            _emittableOperandProvider  = emittableOperandProvider;
            _memberEmitter             = memberEmitter;
            _initializationBuilder     = initializationBuilder;
            _proxySerializationEnabler = proxySerializationEnabler;
        }
コード例 #15
0
        public void RegisterWith(IEmittableOperandProvider emittableOperandProvider, MutableType type)
        {
            ArgumentUtility.CheckNotNull("emittableOperandProvider", emittableOperandProvider);
            ArgumentUtility.CheckNotNull("type", type);

            emittableOperandProvider.AddMapping(type, _typeBuilder);
        }
コード例 #16
0
        public void SetUp()
        {
            _proxy     = MutableTypeObjectMother.Create();
            _addedCtor = _proxy.AddConstructor();

            _tracker = new ProxyTypeModificationTracker(_proxy, new[] { _addedCtor.Body });
        }
コード例 #17
0
        public void SetUp()
        {
            _declaringType = MutableTypeObjectMother.Create(baseType: typeof(DomainType));

            _method        = MutableMethodInfoObjectMother.Create(_declaringType, "NonVirtualMethod");
            _virtualMethod = MutableMethodInfoObjectMother.Create(_declaringType, attributes: MethodAttributes.Virtual);
        }
コード例 #18
0
        public void SetUp()
        {
            _builder = new InitializationBuilder();

            _proxySerializationEnablerMock = new Mock <IProxySerializationEnabler> (MockBehavior.Strict);
            _mutableType = MutableTypeObjectMother.Create();
        }
コード例 #19
0
        private ITargetTypeForNextCall GetTargetTypeWrapper(MutableType concreteTarget, FieldInfo extensionsField)
        {
            ArgumentUtility.CheckNotNull("concreteTarget", concreteTarget);
            ArgumentUtility.CheckNotNull("extensionsField", extensionsField);

            return(new TargetTypeForNextCall(concreteTarget, extensionsField));
        }
コード例 #20
0
ファイル: MethodFactory.cs プロジェクト: re-motion/TypePipe
        private MethodInfo GetBaseMethod(MutableType declaringType, string name, MethodSignature signature, bool isVirtual, bool isNewSlot)
        {
            if (declaringType.IsInterface || !isVirtual || isNewSlot)
            {
                return(null);
            }

            var baseMethod = _relatedMethodFinder.GetMostDerivedVirtualMethod(name, signature, declaringType.BaseType);

            if (baseMethod != null && baseMethod.IsFinal)
            {
                Assertion.IsNotNull(baseMethod.DeclaringType);
                var message = string.Format("Cannot override final method '{0}.{1}'.", baseMethod.DeclaringType.Name, baseMethod.Name);
                throw new NotSupportedException(message);
            }

            if (baseMethod != null && !SubclassFilterUtility.IsVisibleFromSubclass(baseMethod))
            {
                Assertion.IsNotNull(baseMethod.DeclaringType);
                var message = string.Format(
                    "Cannot override method '{0}.{1}' as it is not visible from the proxy.", baseMethod.DeclaringType.Name, baseMethod.Name);
                throw new NotSupportedException(message);
            }

            return(baseMethod);
        }
コード例 #21
0
        public void SetUp()
        {
            _mutableType   = MutableTypeObjectMother.Create();
            _generatedType = typeof(GeneratedType);

            _context = new GeneratedTypesContext(new[] { new KeyValuePair <MutableType, Type> (_mutableType, _generatedType) });
        }
コード例 #22
0
        public void AddMapping(MutableType mappedType, Type emittableType)
        {
            ArgumentUtility.CheckNotNull("mappedType", mappedType);
            ArgumentUtility.CheckNotNull("emittableType", emittableType);

            AddMapping(_mappedTypes, mappedType, emittableType);
        }
コード例 #23
0
        public void SetUp()
        {
            _builder = new InitializationBuilder();

            _proxySerializationEnablerMock = MockRepository.GenerateStrictMock <IProxySerializationEnabler>();
            _mutableType = MutableTypeObjectMother.Create();
        }
コード例 #24
0
        public static MutableType Create(
            Type baseType                  = null,
            string name                    = "MyMutableType",
            string @namespace              = "MyNamespace",
            TypeAttributes attributes      = TypeAttributes.Public | TypeAttributes.BeforeFieldInit,
            MutableType declaringType      = null,
            IMemberSelector memberSelector = null,
            IInterfaceMappingComputer interfaceMappingComputer = null,
            IMutableMemberFactory mutableMemberFactory         = null,
            bool copyCtorsFromBase = false)
        {
            baseType = baseType ?? typeof(UnspecifiedType);
            // Declaring type stays null.

            memberSelector           = memberSelector ?? new MemberSelector(new BindingFlagsEvaluator());
            interfaceMappingComputer = interfaceMappingComputer ?? new InterfaceMappingComputer();
            mutableMemberFactory     = mutableMemberFactory ?? new MutableMemberFactory(new RelatedMethodFinder());

            var mutableType = new MutableType(declaringType, baseType, name, @namespace, attributes, interfaceMappingComputer, mutableMemberFactory);

            mutableType.SetMemberSelector(memberSelector);

            if (copyCtorsFromBase)
            {
                CopyConstructors(baseType, mutableType);
            }

            return(mutableType);
        }
コード例 #25
0
        public void SetUp()
        {
            _declaringType        = ObjectMother.GetMutableType();
            _parameterExpression1 = ObjectMother.GetParameterExpression(typeof(string), "param1");
            _parameterExpression2 = ObjectMother.GetParameterExpression(typeof(int), "param2");
            _thisExpression       = new ThisExpression(_declaringType);

            _callExpressionHelperMock = MockRepository.GenerateStrictMock <ICallExpressionHelper> ();
            _invocationType           = typeof(FuncContext <object, string, int, int>);
            _memberFieldMock          = MockRepository.GenerateStrictMock <IStorage> ();
            _delegateFieldMock        = MockRepository.GenerateStrictMock <IStorage> ();
            _aspectFieldMock1         = MockRepository.GenerateStrictMock <IStorage> ();
            _aspectFieldMock2         = MockRepository.GenerateStrictMock <IStorage> ();
            _adviceMethod1            = ObjectMother.GetMethodInfo();
            _adviceMethod2            = ObjectMother.GetMethodInfo();
            var advices = new[] { Tuple.Create(_adviceMethod1, _aspectFieldMock1), Tuple.Create(_adviceMethod2, _aspectFieldMock2) };

            _expressionHelper = new InterceptionExpressionHelper(
                _callExpressionHelperMock,
                _thisExpression,
                new[] { _parameterExpression1, _parameterExpression2 },
                _invocationType,
                advices,
                _memberFieldMock,
                _delegateFieldMock);
        }
コード例 #26
0
        protected BodyContextBase(MutableType declaringType, bool isStatic)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);

            _declaringType = declaringType;
            _isStatic      = isStatic;
        }
コード例 #27
0
 /// <summary>
 /// Adds the default control states for a control.
 /// In this implementation, the default control states are:
 /// Create state: Control is enabled.
 /// Read state: Control is disabled.
 /// Update state: Control state as specific by "mutable" parameter
 /// Delete state: Control is disabled.
 /// </summary>
 /// <param name="id">
 /// Control identifier
 /// </param>
 /// <param name="mutable">
 /// Mutability of control.
 /// </param>
 private void AddControlDefaultStates(string id, MutableType mutable)
 {
     AddControlState(CRUDStates.CreateState, new GUIControlState(id, true));
     AddControlState(CRUDStates.ReadState, new GUIControlState(id, false));
     AddControlState(CRUDStates.UpdateState, new GUIControlState(id, mutable == MutableType.Mutable));
     AddControlState(CRUDStates.DeleteState, new GUIControlState(id, false));
 }
コード例 #28
0
        public void SetUp()
        {
            _mutableType = MutableTypeObjectMother.Create(baseType: typeof(DomainType));

            _context       = new TestableBodyContextBase(_mutableType, isStatic: false);
            _staticContext = new TestableBodyContextBase(_mutableType, isStatic: true);
        }
コード例 #29
0
        public void Initialization()
        {
            var declaringType = MutableTypeObjectMother.Create(name: "DeclaringType");
            var baseType      = ReflectionObjectMother.GetSomeSubclassableType();
            var name          = "MyType";
            var @namespace    = "MyNs";
            var attributes    = (TypeAttributes)7;

            var mutableType = new MutableType(
                declaringType, baseType, name, @namespace, attributes, _interfaceMappingComputerMock, _mutableMemberFactoryMock);

            Assert.That(mutableType.DeclaringType, Is.SameAs(declaringType));
            Assert.That(mutableType.MutableDeclaringType, Is.SameAs(declaringType));
            Assert.That(mutableType.BaseType, Is.SameAs(baseType));
            Assert.That(mutableType.Name, Is.EqualTo(name));
            Assert.That(mutableType.Namespace, Is.EqualTo(@namespace));
            Assert.That(mutableType.FullName, Is.EqualTo("MyNs.DeclaringType+MyType"));
            Assert.That(mutableType.Attributes, Is.EqualTo(attributes));
            Assert.That(mutableType.IsGenericType, Is.False);
            Assert.That(mutableType.IsGenericTypeDefinition, Is.False);
            Assert.That(mutableType.GetGenericArguments(), Is.Empty);

            Assert.That(mutableType.AddedNestedTypes, Is.Empty);
            Assert.That(mutableType.AddedCustomAttributes, Is.Empty);
            Assert.That(mutableType.Initialization, Is.Not.Null);
            Assert.That(mutableType.AddedInterfaces, Is.Empty);
            Assert.That(mutableType.AddedFields, Is.Empty);
            Assert.That(mutableType.AddedConstructors, Is.Empty);
            Assert.That(mutableType.AddedMethods, Is.Empty);
            Assert.That(mutableType.AddedProperties, Is.Empty);
            Assert.That(mutableType.AddedEvents, Is.Empty);
        }
コード例 #30
0
        private MethodInfo GetOrCreateImplementationMethod(MutableType declaringType, MethodInfo ifcMethod, out bool isNewlyCreated)
        {
            var interfaceMap   = declaringType.GetInterfaceMap(ifcMethod.DeclaringType, allowPartialInterfaceMapping: true);
            var index          = Array.IndexOf(interfaceMap.InterfaceMethods, ifcMethod);
            var implementation = interfaceMap.TargetMethods[index];

            if (implementation != null)
            {
                isNewlyCreated = false;
                return(implementation);
            }
            isNewlyCreated = true;

            try
            {
                return(CreateMethod(declaringType, ifcMethod, ifcMethod.Name, ifcMethod.Attributes, bodyProvider: null));
            }
            catch (InvalidOperationException)
            {
                var message = string.Format(
                    "Interface method '{0}' cannot be implemented because a method with equal name and signature already exists. "
                    + "Use AddExplicitOverride to create an explicit implementation.",
                    ifcMethod.Name);
                throw new InvalidOperationException(message);
            }
        }