예제 #1
0
        public InterfaceImplementation(
            TypeBuilder typeBuilder,
            Type @interface,
            GenericParameterMapper genericParameterMapper,
            FieldBuilder proxyInterceptionPipelineField,
            bool explicitImplementation,
            FieldBuilder targetField)
        {
            this.typeBuilder                    = typeBuilder;
            this.@interface                     = @interface;
            this.genericParameterMapper         = genericParameterMapper;
            this.proxyInterceptionPipelineField = proxyInterceptionPipelineField;
            this.explicitImplementation         = explicitImplementation;
            this.targetField                    = targetField;

            if (@interface.IsGenericType)
            {
                // when the @interface is generic we need to get references to its methods though it
                // in this case, the targetInterface is a constructed version using the generic type parameters
                // from the generated type generate type
                var definition       = @interface.GetGenericTypeDefinition();
                var mappedParameters = definition.GetGenericArguments().Select(t => genericParameterMapper.Map(t)).ToArray();
                this.targetInterface = definition.MakeGenericType(mappedParameters);
            }
            else
            {
                this.targetInterface = @interface;
            }
        }
        public void SetupParameters(MethodBuilder methodBuilder, GenericParameterMapper parentMapper)
        {
            if (methodToOverride.IsGenericMethod)
            {
                var genericArguments = methodToOverride.GetGenericArguments();
                var names            = genericArguments.Select(t => t.Name).ToArray();
                var builders         = methodBuilder.DefineGenericParameters(names);
                for (int i = 0; i < genericArguments.Length; ++i)
                {
                    builders[i].SetGenericParameterAttributes(genericArguments[i].GenericParameterAttributes);

                    var constraintTypes =
                        genericArguments[i]
                        .GetGenericParameterConstraints()
                        .Select(ct => parentMapper.Map(ct))
                        .ToArray();

                    var  interfaceConstraints = constraintTypes.Where(t => t.IsInterface).ToArray();
                    Type baseConstraint       = constraintTypes.Where(t => !t.IsInterface).FirstOrDefault();
                    if (baseConstraint != null)
                    {
                        builders[i].SetBaseTypeConstraint(baseConstraint);
                    }
                    if (interfaceConstraints.Length > 0)
                    {
                        builders[i].SetInterfaceConstraints(interfaceConstraints);
                    }
                }

                this.genericParameterMapper =
                    new GenericParameterMapper(genericArguments, builders.Cast <Type>().ToArray(), parentMapper);
            }
            else
            {
                this.genericParameterMapper = parentMapper;
            }
        }