private void CreateTypeBuilder()
        {
            TypeAttributes newAttributes = typeToIntercept.Attributes;

            newAttributes = FilterTypeAttributes(newAttributes);

            Type baseClass = GetGenericType(typeToIntercept);

            ModuleBuilder moduleBuilder = GetModuleBuilder();

            typeBuilder = moduleBuilder.DefineType(
                "DynamicModule.ns.Wrapped_" + typeToIntercept.Name + "_" + Guid.NewGuid().ToString("N"),
                newAttributes,
                baseClass);

            this.mainTypeMapper = DefineGenericArguments(typeBuilder, baseClass);

            if (this.typeToIntercept.IsGenericType)
            {
                var definition       = this.typeToIntercept.GetGenericTypeDefinition();
                var mappedParameters = definition.GetGenericArguments().Select(t => this.mainTypeMapper.Map(t)).ToArray();
                this.targetType = definition.MakeGenericType(mappedParameters);
            }
            else
            {
                this.targetType = this.typeToIntercept;
            }

            proxyInterceptionPipelineField = InterceptingProxyImplementor.ImplementIInterceptingProxy(typeBuilder);
        }
예제 #2
0
        internal MethodOverride(
            TypeBuilder typeBuilder,
            FieldBuilder proxyInterceptionPipelineField,
            MethodInfo methodToOverride,
            Type targetType,
            GenericParameterMapper targetTypeParameterMapper,
            int overrideCount)
        {
            this.typeBuilder = typeBuilder;
            this.proxyInterceptionPipelineField = proxyInterceptionPipelineField;
            this.methodToOverride = methodToOverride;
            this.methodParameters = methodToOverride.GetParameters();
            this.targetType       = targetType;

            // if the method is inherited and the declaring type is generic, we need to map
            // the parameters of the original declaration to the actual intercepted type type
            // E.g. consider given class Type1<T> with virtual method "T Method<U>()", the mappings in
            // different scenarios would look like:
            // Type2<S> : Type2<S>                  => S Method<U>()
            // Type2<S> : Type2<IEnumerable<S>>     => IEnumerable<S> Method<U>()
            // Type2 : Type1<IEnumerable<string>>   => IEnumerable<string> Method<U>()
            var declaringType = methodToOverride.DeclaringType;

            this.targetTypeParameterMapper =
                declaringType.IsGenericType && declaringType != methodToOverride.ReflectedType
                    ? new GenericParameterMapper(declaringType, targetTypeParameterMapper)
                    : targetTypeParameterMapper;
            this.overrideCount = overrideCount;
        }
예제 #3
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;
            }
        }
        private void CreateTypeBuilder()
        {
            TypeAttributes newAttributes = TypeAttributes.Public | TypeAttributes.Class;

            ModuleBuilder moduleBuilder = GetModuleBuilder();

            typeBuilder = moduleBuilder.DefineType(CreateTypeName(), newAttributes);

            mainInterfaceMapper = DefineGenericArguments();

            proxyInterceptionPipelineField = InterceptingProxyImplementor.ImplementIInterceptingProxy(typeBuilder);
            targetField      = typeBuilder.DefineField("target", typeToIntercept, FieldAttributes.Private);
            typeToProxyField = typeBuilder.DefineField("typeToProxy", typeof(Type), FieldAttributes.Private);
        }
예제 #5
0
 internal InterfaceMethodOverride(
     TypeBuilder typeBuilder,
     FieldBuilder proxyInterceptionPipelineField,
     FieldBuilder targetField,
     MethodInfo methodToOverride,
     Type targetInterface,
     GenericParameterMapper targetInterfaceParameterMapper,
     bool explicitImplementation,
     int overrideCount)
 {
     this.typeBuilder = typeBuilder;
     this.proxyInterceptionPipelineField = proxyInterceptionPipelineField;
     this.explicitImplementation         = explicitImplementation;
     this.targetField      = targetField;
     this.methodToOverride = methodToOverride;
     this.targetInterface  = targetInterface;
     this.targetInterfaceParameterMapper = targetInterfaceParameterMapper;
     this.methodParameters = methodToOverride.GetParameters();
     this.overrideCount    = overrideCount;
 }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GenericParameterMapper"/> class.
        /// </summary>
        /// <param name="type">A constructed generic type, open or closed.</param>
        /// <param name="parent">The parent mapper, or <see langword="null"/>.</param>
        public GenericParameterMapper(Type type, GenericParameterMapper parent)
        {
            Guard.ArgumentNotNull(type, "type");

            if (type.IsGenericType)
            {
                if (type.IsGenericTypeDefinition)
                {
                    throw new ArgumentException(Resources.ExceptionCannotMapGenericTypeDefinition, "type");
                }

                this.parent        = parent;
                this.localMappings =
                    CreateMappings(
                        type.GetGenericTypeDefinition().GetGenericArguments(),
                        type.GetGenericArguments());
            }
            else
            {
                this.localMappings = EmptyMappings;
                this.parent        = null;
            }
        }
        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;
            }
        }
예제 #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GenericParameterMapper"/> class.
 /// </summary>
 /// <param name="reflectedParameters">The reflected generic parameters.</param>
 /// <param name="generatedParameters">The generated generic parameters.</param>
 /// <param name="parent">The parent mapper, or <see langword="null"/>.</param>
 public GenericParameterMapper(Type[] reflectedParameters, Type[] generatedParameters, GenericParameterMapper parent)
 {
     this.parent        = parent;
     this.localMappings = CreateMappings(reflectedParameters, generatedParameters);
 }