protected override void InitializeFields()
        {
            base.InitializeFields();

            _targetField = new TargetFieldMetadata("_target", _proxyDefinition.TargetType);

            Fields.Add(_targetField);
        }
        private static FieldBuilder GenerateField(TypeBuilder typeBuilder, FieldMetadata fieldMetadata)
        {
            var field = typeBuilder.DefineField(
                fieldMetadata.Name,
                fieldMetadata.FieldType,
                fieldMetadata.FieldAttributes);

            return field;
        }
        public static MethodMetadata Create(
            IProxyDefinitionElement definitionElement, 
            FieldMetadata targetField, 
            MethodInfo method)
        {
            var classProxyDefinition = definitionElement as ClassProxyDefinition;

            if (classProxyDefinition != null)
            {
                return new ClassMethodMetadata(method);
            }

            var interfaceProxyDefinition = definitionElement as InterfaceProxyDefinition;

            if (interfaceProxyDefinition != null)
            {
                return new NonTargetedMethodMetadata(method);
            }

            var targetedClassProxyDefinition = definitionElement as TargetedClassProxyDefinition;

            if (targetedClassProxyDefinition != null)
            {
                var targetMethod = MemberLocator.LocateMatchingMethod(method, targetedClassProxyDefinition.TargetType);

                return new TargetedMethodMetadata(method, targetField, targetMethod);
            }

            var targetedInterfaceProxyDefinition = definitionElement as TargetedInterfaceProxyDefinition;

            if (targetedInterfaceProxyDefinition != null)
            {
                var targetMethod = MemberLocator.LocateMatchingMethod(method, targetedInterfaceProxyDefinition.TargetType);

                return new TargetedMethodMetadata(method, targetField, targetMethod);
            }

            var mixinInterfaveDefinition = definitionElement as MixinInterfaceDefinition;

            if (mixinInterfaveDefinition != null)
            {
                var targetMethod = MemberLocator.LocateMatchingMethod(method, mixinInterfaveDefinition.MixinType);

                return new TargetedMethodMetadata(method, targetField, targetMethod);
            }

            var nonTargetefInterfaceDefinition = definitionElement as NonTargetedInterfaceDefinition;

            if (nonTargetefInterfaceDefinition != null)
            {
                return new NonTargetedMethodMetadata(method);
            }

            throw new NotSupportedException();
        }
        public TargetedMethodMetadata(MethodInfo method, FieldMetadata targetField, MethodInfo targetMethod)
            : base(method)
        {
            _targetField = targetField;
            _targetMethod = targetMethod;

            _methodAttributes = method.Attributes;

            _methodAttributes &= ~MethodAttributes.NewSlot;
            _methodAttributes &= ~MethodAttributes.Abstract;
            _methodAttributes |= MethodAttributes.ReuseSlot | MethodAttributes.Final;
        }
        private static void InitializeField(
            ILGenerator il,
            FieldMetadata instanceField, 
            ConstructorParameterMetadata dispatcherParameter,
            FieldMetadataFieldBuilderMap fieldBuilders)
        {
            var fieldBuilder = fieldBuilders[instanceField];

            new StoreFieldStatement(fieldBuilder,
                new LoadArgumentExpression(dispatcherParameter.Sequence)
            ).Emit(il);
        }
 public TypeMetadata(
     string name,
     Type baseType,
     Type[] interfaces,
      DispatcherFieldMetadata dispatcherField,
     FieldMetadata[] fields,
     ConstructorMetadata[] constructors, 
     MethodMetadata[] methods, 
     PropertyMetadata[] properties, 
     EventMetadata[] events, 
     TargetMetadata[] targets)
 {
     _name = name;
     _baseType = baseType;
     _interfaces = interfaces;
     _dispatcherField = dispatcherField;
     _fields = fields;
     _constructors = constructors;
     _methods = methods;
     _properties = properties;
     _events = events;
     _targets = targets;
 }
 public ConstructorTargetParameterMetadata(int sequence, string name, FieldMetadata instanceField)
     : base(sequence, name, instanceField.FieldType)
 {
     _instanceField = instanceField;
 }
        private MethodMetadata CreateMethodMetadata(
            IProxyDefinitionElement definition, 
            FieldMetadata targetField,
            MethodInfo method, 
            bool implementExplicitly)
        {
            var result = MethodMetadataFactory.Create(definition, targetField, method);

            if (implementExplicitly)
            {
                result.UseExplicitInterfaceImplementation();
            }

            _methods.Add(result);

            return result;
        }
        protected void InitializeDefinitionProperties(
            IProxyDefinitionElement definition, 
            FieldMetadata targetField,
            bool implementExplicitly)
        {
            var properties = definition.Type.GetProperties(ProxyBindingFlags);

            for (var i = 0; i < properties.Length; i++)
            {
                var property = properties[i];

                var getMethod = property.GetGetMethod();
                var setMethod = property.GetSetMethod();

                MethodMetadata getMethodMetadata = null;
                MethodMetadata setMethodMetadata = null;

                if (getMethod != null && getMethod.IsVirtual)
                {
                    getMethodMetadata = CreateMethodMetadata(definition, targetField, getMethod, implementExplicitly);
                }

                if (setMethod != null && setMethod.IsVirtual)
                {
                    setMethodMetadata = CreateMethodMetadata(definition, targetField, setMethod, implementExplicitly);
                }

                if (getMethodMetadata != null || setMethodMetadata != null)
                {
                    _properties.Add(new PropertyMetadata(properties[i], getMethodMetadata, setMethodMetadata));
                }
            }
        }
        protected void InitializeDefinitionMethods(
            IProxyDefinitionElement definition, 
            FieldMetadata targetField, 
            bool implementExplicitly)
        {
            var definitionMethods = definition.Type.GetMethods(ProxyBindingFlags);

            for (var i = 0; i < definitionMethods.Length; i++)
            {
                var method = definitionMethods[i];

                if (ShouldBuildMethodMetadata(method))
                {
                    CreateMethodMetadata(definition, targetField, method, implementExplicitly);
                }
            }
        }
        protected virtual void InitializeDefinitionEvents(
            IProxyDefinitionElement definition, 
            FieldMetadata targetField, 
            bool implementExplicitly)
        {
            var events = definition.Type.GetEvents(ProxyBindingFlags);

            for (var i = 0; i < events.Length; i++)
            {
                var @event = events[i];

                var addMethod = @event.GetAddMethod();
                var removeMethod = @event.GetRemoveMethod();
                var raiseMethod = @event.GetRaiseMethod();

                MethodMetadata addMethodMetadata = null;
                MethodMetadata removeMethodMetadata = null;
                MethodMetadata raiseMethodMetadata = null;

                if (addMethod.IsVirtual)
                {
                    addMethodMetadata = CreateMethodMetadata(definition, targetField, addMethod, implementExplicitly);
                }

                if (removeMethod.IsVirtual)
                {
                    removeMethodMetadata = CreateMethodMetadata(definition, targetField, removeMethod, implementExplicitly);
                }

                if (raiseMethod != null && raiseMethod.IsVirtual)
                {
                    raiseMethodMetadata = CreateMethodMetadata(definition, targetField, raiseMethod, implementExplicitly);
                }

                if (addMethodMetadata != null ||
                    removeMethodMetadata != null ||
                    raiseMethodMetadata != null)
                {
                    _events.Add(new EventMetadata(events[i], addMethodMetadata, removeMethodMetadata, raiseMethodMetadata));
                }
            }
        }
        private static void InitializeTarget(
            ILGenerator il, 
            FieldMetadata instanceField, 
            Type targetType,
            FieldMetadataFieldBuilderMap fieldBuilders)
        {
            var fieldBuilder = fieldBuilders[instanceField];

            var defaultConstructor = targetType.GetConstructor(
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                null,
                Type.EmptyTypes,
                null);

            new StoreFieldStatement(fieldBuilder,
                new NewObjectExpression(defaultConstructor)
            ).Emit(il);
        }