Exemplo n.º 1
0
        public void DefineCustomAttribute <TAttribute>() where TAttribute : Attribute, new()
        {
            var customAttributeInfo = AttributeUtil.CreateInfo <TAttribute>();

            typebuilder.SetCustomAttribute(customAttributeInfo.Builder);
        }
Exemplo n.º 2
0
        protected void GenerateConstructor(ClassEmitter emitter, ConstructorInfo baseConstructor,
                                           params FieldReference[] fields)
        {
            ArgumentReference[] args;
            ParameterInfo[]     baseConstructorParams = null;

            if (baseConstructor != null)
            {
                baseConstructorParams = baseConstructor.GetParameters();
            }

            if (baseConstructorParams != null && baseConstructorParams.Length != 0)
            {
                args = new ArgumentReference[fields.Length + baseConstructorParams.Length];

                var offset = fields.Length;
                for (var i = offset; i < offset + baseConstructorParams.Length; i++)
                {
                    var paramInfo = baseConstructorParams[i - offset];
                    args[i] = new ArgumentReference(paramInfo.ParameterType);
                }
            }
            else
            {
                args = new ArgumentReference[fields.Length];
            }

            for (var i = 0; i < fields.Length; i++)
            {
                args[i] = new ArgumentReference(fields[i].Reference.FieldType);
            }

            var constructor = emitter.CreateConstructor(args);

            if (baseConstructorParams != null && baseConstructorParams.Length != 0)
            {
                var last = baseConstructorParams.Last();
                if (last.ParameterType.GetTypeInfo().IsArray&& last.IsDefined(typeof(ParamArrayAttribute)))
                {
                    var parameter = constructor.ConstructorBuilder.DefineParameter(args.Length, ParameterAttributes.None, last.Name);
                    var info      = AttributeUtil.CreateInfo <ParamArrayAttribute>();
                    parameter.SetCustomAttribute(info.Builder);
                }
            }

            for (var i = 0; i < fields.Length; i++)
            {
                constructor.CodeBuilder.AddStatement(new AssignStatement(fields[i], args[i].ToExpression()));
            }

            // Invoke base constructor

            if (baseConstructor != null)
            {
                Debug.Assert(baseConstructorParams != null);

                var slice = new ArgumentReference[baseConstructorParams.Length];
                Array.Copy(args, fields.Length, slice, 0, baseConstructorParams.Length);

                constructor.CodeBuilder.InvokeBaseConstructor(baseConstructor, slice);
            }
            else
            {
                constructor.CodeBuilder.InvokeBaseConstructor();
            }

            constructor.CodeBuilder.AddStatement(new ReturnStatement());
        }
Exemplo n.º 3
0
        public void DefineCustomAttribute <TAttribute>(object[] constructorArguments) where TAttribute : Attribute
        {
            var customAttributeInfo = AttributeUtil.CreateInfo(typeof(TAttribute), constructorArguments);

            typebuilder.SetCustomAttribute(customAttributeInfo.Builder);
        }
Exemplo n.º 4
0
        public object Create(object some = null, Type typeToTrack = null, ObjectChangeTracker reusedTracker = null, object parentObject = null, PropertyInfo propertyToSet = null, object[] constructorArguments = null)
        {
            typeToTrack = typeToTrack ?? some.GetType();

            ITrackableType interfaceTrackableType = null;

            if ((Configuration.CanTrackType(typeToTrack) || Configuration.ImplementsBaseType(typeToTrack, out interfaceTrackableType)) && !typeToTrack.IsTrackable())
            {
                if (interfaceTrackableType != null)
                {
                    Configuration.TrackThisTypeRecursive
                    (
                        typeToTrack,
                        trackableType =>
                    {
                        if (trackableType.Type == typeToTrack)
                        {
                            trackableType.IncludeProperties(interfaceTrackableType.IncludedProperties.ToArray());
                        }
                    }
                    );
                }

                TypeInfo typeToTrackInfo = typeToTrack.GetTypeInfo();

                Contract.Assert(() => typeToTrackInfo.IsClass && !typeToTrackInfo.IsAbstract && !typeToTrackInfo.IsSealed, $"The object type to track '{typeToTrack.AssemblyQualifiedName}' must be a non-abstract, non-sealed class");

                ProxyGenerationOptions options = new ProxyGenerationOptions(new SimplePropertyInterceptionHook(Configuration));
                options.AddMixinInstance(new ChangeTrackableObjectMixin(Configuration, this));
                options.AdditionalAttributes.Add(AttributeUtil.CreateInfo(typeof(DebuggerDisplayAttribute), new[] { $"{typeToTrack.FullName}Proxy" }));

                List <IInterceptor> interceptors = new List <IInterceptor>
                {
                    new SimplePropertyInterceptor()
                };

                if (typeToTrack.IsDynamicObject())
                {
                    interceptors.Add(new DynamicObjectInterceptor(Configuration, this));
                }

                object proxy;

                if (some != null)
                {
                    proxy = ProxyGenerator.CreateClassProxyWithTarget
                            (
                        classToProxy: typeToTrack,
                        additionalInterfacesToProxy: new[] { typeof(IChangeTrackableObject) },
                        target: some,
                        options: options,
                        interceptors: interceptors.ToArray()
                            );
                }
                else
                {
                    proxy = ProxyGenerator.CreateClassProxy
                            (
                        classToProxy: typeToTrack,
                        additionalInterfacesToProxy: new[] { typeof(IChangeTrackableObject) },
                        options: options,
                        constructorArguments: constructorArguments,
                        interceptors: interceptors.ToArray()
                            );
                }


                IChangeTrackableObject      trackableObject = (IChangeTrackableObject)proxy;
                ObjectChangeTrackingContext trackingContext = trackableObject.GetChangeTrackingContext();

                trackingContext.State = ChangeTrackableObjectState.Constructing;
                trackableObject.StartTracking(trackableObject, reusedTracker);
                trackingContext.State = ChangeTrackableObjectState.Ready;

                HashSet <PropertyInfo> propertiesToTrack =
                    new HashSet <PropertyInfo>(Configuration.GetTrackableType(typeToTrack).IncludedProperties);

                if (propertiesToTrack.Count() == 0)
                {
                    foreach (PropertyInfo property in typeToTrack.GetProperties(BindingFlags.Instance | BindingFlags.Public))
                    {
                        propertiesToTrack.Add(property);
                    }
                }

                foreach (PropertyInfo property in propertiesToTrack)
                {
                    if (!property.IsIndexer() && property.CanReadAndWrite())
                    {
                        object propertyValue = property.GetValue(trackableObject);

                        if (propertyValue != null)
                        {
                            Create(propertyValue, trackableObject.GetChangeTrackingContext().ChangeTracker, proxy, property);
                        }
                        else
                        {
                            Create(property.PropertyType, trackableObject.GetChangeTrackingContext().ChangeTracker, proxy, property);
                        }
                    }
                }

                if (propertyToSet != null)
                {
                    propertyToSet.SetValue(parentObject ?? proxy, proxy);
                }

                trackableObject.AcceptChanges();

                return(proxy);
            }
            else
            {
                return(some);
            }
        }