예제 #1
0
        /// <summary>
        /// Finds the properties that represent a <see cref="PropertyData"/>.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The list of <see cref="PropertyData"/> elements found as properties.</returns>
        /// <exception cref="InvalidOperationException">One ore more properties are not declared correctly.</exception>
        private IEnumerable <PropertyData> FindCatelProperties(Type type)
        {
            // CTL-212: Generic types are not supported for FieldInfo.GetValue
            if (type.ContainsGenericParametersEx())
            {
                return(ArrayShim.Empty <PropertyData>());
            }

            PreventWrongDeclaredProperties(type);

            // Properties - actual addition
            var foundProperties = new List <PropertyData>();

            var properties = new List <PropertyInfo>();

            properties.AddRange(type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, true), true));
            foreach (var property in properties)
            {
                if (property.PropertyType == typeof(PropertyData))
                {
                    var propertyValue = property.GetValue(null, null) as PropertyData;
                    if (propertyValue != null)
                    {
                        foundProperties.Add(propertyValue);
                    }
                }
            }

            return(foundProperties);
        }
예제 #2
0
        /// <summary>
        ///     The get property ex.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="name">The name.</param>
        /// <param name="flattenHierarchy">The flatten hierarchy.</param>
        /// <param name="allowStaticMembers">The allow static members.</param>
        /// <param name="allowExplicitInterfaceProperties">
        ///     if set to <c>true</c>, this method will check for explicit interface implementations when the property
        ///     is not found.
        /// </param>
        /// <returns>PropertyInfo.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="type" /> is <c>null</c>.</exception>
        /// <exception cref="System.ArgumentException">The <paramref name="name" /> is <c>null</c> or whitespace.</exception>
        public static PropertyInfo GetPropertyEx(this Type type, string name, bool flattenHierarchy = true, bool allowStaticMembers = false,
                                                 bool allowExplicitInterfaceProperties = true)
        {
            var bindingFlags = BindingFlagsHelper.GetFinalBindingFlags(flattenHierarchy, allowStaticMembers);

            return(GetPropertyEx(type, name, bindingFlags, allowExplicitInterfaceProperties));
        }
예제 #3
0
        /// <summary>
        /// Finds the fields that represent a <see cref="PropertyData"/>.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The list of <see cref="PropertyData"/> elements found as fields.</returns>
        /// <exception cref="InvalidOperationException">One ore more fields are not declared correctly.</exception>
        private IEnumerable <PropertyData> FindCatelFields(Type type)
        {
            // CTL-212: Generic types are not supported for FieldInfo.GetValue
            if (type.ContainsGenericParametersEx())
            {
                return(ArrayShim.Empty <PropertyData>());
            }

            PreventWrongDeclaredFields(type);

            // Fields - actual addition
            var foundFields = new List <PropertyData>();

            var fields = new List <FieldInfo>();

            fields.AddRange(type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, false)));
            foreach (var field in fields)
            {
                if (field.FieldType == typeof(PropertyData))
                {
                    var propertyValue = (field.IsStatic ? field.GetValue(null) : field.GetValue(this)) as PropertyData;
                    if (propertyValue != null)
                    {
                        foundFields.Add(propertyValue);
                    }
                }
            }

            return(foundFields);
        }
예제 #4
0
        /// <summary>
        /// Finds the non catel properties.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The list of <see cref="PropertyInfo"/> elements found as properties.</returns>
        private static IEnumerable <PropertyInfo> FindNonCatelProperties(Type type)
        {
            var properties = (from property in type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true))
                              where property.PropertyType != typeof(PropertyData)
                              select property).ToList();

            return(properties);
        }
예제 #5
0
        /// <summary>
        /// Gets the fields from an enum.
        /// </summary>
        /// <param name="enumType">Type of the enum.</param>
        /// <returns>Array of <see cref="FieldInfo"/> values.</returns>
        private static FieldInfo[] GetFields(Type enumType)
        {
            var fields = from field in enumType.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, true))
                         where field.IsLiteral
                         select field;

            return(fields.ToArray());
        }
예제 #6
0
        private void AddTypeMembers(Type type, XmlSerializerTypeInfo serializerTypeInfo)
        {
            var typesToCheck = new List <Type>();

            var isModelBase = (type == typeof(ModelBase)) || typeof(ModelBase).IsAssignableFromEx(type);

            if (isModelBase)
            {
                // No need to check members, they will be serialized by ModelBase
                //var catelTypeInfo = PropertyDataManager.Default.GetCatelTypeInfo(type);
                //var modelBaseProperties = catelTypeInfo.GetCatelProperties();
                //foreach (var modelBaseProperty in modelBaseProperties)
                //{
                //    typesToCheck.Add(modelBaseProperty.Value.Type);
                //}
            }
            else
            {
                bool allowNonPublicReflection = AllowNonPublicReflection(type);

                // Fields
                var fields = type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(false, false, allowNonPublicReflection));
                foreach (var field in fields)
                {
                    typesToCheck.Add(field.FieldType);
                }

                // Properties
                var properties = type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(false, false, allowNonPublicReflection));
                foreach (var property in properties)
                {
                    typesToCheck.Add(property.PropertyType);
                }
            }

            foreach (var typeToCheck in typesToCheck)
            {
                if (serializerTypeInfo.IsTypeAlreadyHandled(typeToCheck))
                {
                    continue;
                }

                if (!IsTypeSerializable(typeToCheck, serializerTypeInfo))
                {
                    serializerTypeInfo.AddTypeAsHandled(typeToCheck);
                    continue;
                }

                var propertyTypeFullName = typeToCheck.GetSafeFullName();
                if (propertyTypeFullName == null)
                {
                    serializerTypeInfo.AddTypeAsHandled(typeToCheck);
                    continue;
                }

                GetKnownTypes(typeToCheck, serializerTypeInfo);
            }
        }
        private void AddTypeMembers(Type type, XmlSerializerTypeInfo serializerTypeInfo)
        {
            var isModelBase = (type == typeof(ModelBase)) || typeof(ModelBase).IsAssignableFromEx(type);

            if (isModelBase)
            {
                var catelTypeInfo       = PropertyDataManager.Default.GetCatelTypeInfo(type);
                var modelBaseProperties = catelTypeInfo.GetCatelProperties();
                foreach (var modelBaseProperty in modelBaseProperties)
                {
                    var propertyType = modelBaseProperty.Value.Type;
                    if (propertyType.FullName != null)
                    {
                        GetKnownTypes(propertyType, serializerTypeInfo);
                    }
                    else
                    {
                        serializerTypeInfo.AddTypeAsHandled(propertyType);
                    }
                }
            }
            else
            {
                bool allowNonPublicReflection = AllowNonPublicReflection(type);

                // Fields
                var fields = type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(false, false, allowNonPublicReflection));
                foreach (var field in fields)
                {
                    var fieldType = field.FieldType;
                    if (fieldType.FullName != null)
                    {
                        GetKnownTypes(fieldType, serializerTypeInfo);
                    }
                    else
                    {
                        serializerTypeInfo.AddTypeAsHandled(fieldType);
                    }
                }

                // Properties
                var properties = type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(false, false, allowNonPublicReflection));
                foreach (var property in properties)
                {
                    var propertyType = property.PropertyType;
                    if (propertyType.FullName != null)
                    {
                        GetKnownTypes(propertyType, serializerTypeInfo);
                    }
                    else
                    {
                        serializerTypeInfo.AddTypeAsHandled(propertyType);
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Gets the fields from an enum.
        /// </summary>
        /// <param name="enumType">Type of the enum.</param>
        /// <returns>Array of <see cref="FieldInfo"/> values.</returns>
        private static FieldInfo[] GetFields(Type enumType)
        {
            var fields = enumType.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, true));

            fields = (from field in fields
                      where field.IsLiteral && field.IsPublic
                      select field).ToArray();

            return(fields.ToArray());
        }
예제 #9
0
        /// <summary>
        /// Finds the fields that represent a <see cref="PropertyData"/>.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The list of <see cref="PropertyData"/> elements found as fields.</returns>
        /// <exception cref="InvalidOperationException">One ore more fields are not declared correctly.</exception>
        private IEnumerable <PropertyData> FindCatelFields(Type type)
        {
            // CTL-212: Generic types are not supported for FieldInfo.GetValue
            if (type.ContainsGenericParametersEx())
            {
                return(new PropertyData[] { });
            }

            // Fields - safety checks for non-static fields
            var nonStaticFields = (from field in type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true))
                                   where field.FieldType == typeof(PropertyData)
                                   select field).ToList();

            foreach (var nonStaticField in nonStaticFields)
            {
                string error = string.Format("The field '{0}' of type 'PropertyData' declared as instance, but they can only be used as static", nonStaticField.Name);

                Log.Error(error);
                throw new InvalidOperationException(error);
            }

            // Fields - safety checks for non-public fields
            var nonPublicFields = (from field in type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, true))
                                   where field.FieldType == typeof(PropertyData) && !field.IsPublic
                                   select field).ToList();

            foreach (var nonPublicField in nonPublicFields)
            {
                string error = string.Format("The field '{0}' of type 'PropertyData' declared as non-public, but they can only be used as public", nonPublicField.Name);

                Log.Error(error);
                throw new InvalidOperationException(error);
            }

            // Fields - actual addition
            var foundFields = new List <PropertyData>();

            var fields = new List <FieldInfo>();

            fields.AddRange(type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, false)));
            foreach (var field in fields)
            {
                if (field.FieldType == typeof(PropertyData))
                {
                    var propertyValue = (field.IsStatic ? field.GetValue(null) : field.GetValue(this)) as PropertyData;
                    if (propertyValue != null)
                    {
                        foundFields.Add(propertyValue);
                    }
                }
            }

            return(foundFields);
        }
예제 #10
0
        /// <summary>
        ///     The get events ex.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="flattenHierarchy">The flatten Hierarchy.</param>
        /// <param name="allowStaticMembers">The allow Static Members.</param>
        /// <returns>EventInfo[][].</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="type" /> is <c>null</c>.</exception>
        public static EventInfo[] GetEventsEx(this Type type, bool flattenHierarchy = true, bool allowStaticMembers = false)
        {
            Argument.IsNotNull(nameof(type), type);
            var bindingFlags = BindingFlagsHelper.GetFinalBindingFlags(flattenHierarchy, allowStaticMembers);

#if ENABLE_CACHE
            var cacheKey = new ReflectionCacheKey(type, ReflectionTypes.Event, bindingFlags);
            return(_eventsCache.GetFromCacheOrFetch(cacheKey, () => type.GetTypeInfo().GetEvents(bindingFlags)));
#else
            return(type.GetTypeInfo().GetEvents(bindingFlags));
#endif
        }
예제 #11
0
        private void PreventWrongDeclaredProperties(Type type)
        {
            // Properties - safety checks for non-static properties
            var nonStaticProperties = (from property in type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true))
                                       where property.PropertyType == typeof(PropertyData)
                                       select property).ToList();

            if (nonStaticProperties.Count > 0)
            {
                var nonStaticProperty = nonStaticProperties[0];
                throw Log.ErrorAndCreateException <InvalidOperationException>("The property '{0}' of type 'PropertyData' declared as instance, but they can only be used as static", nonStaticProperty.Name);
            }
        }
예제 #12
0
        private void PreventWrongDeclaredFields(Type type)
        {
            // Fields - safety checks for non-static fields
            var nonStaticFields = (from field in type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true))
                                   where field.FieldType == typeof(PropertyData)
                                   select field).ToList();

            if (nonStaticFields.Count > 0)
            {
                var nonStaticField = nonStaticFields[0];
                throw Log.ErrorAndCreateException <InvalidOperationException>("The field '{0}' of type 'PropertyData' declared as instance, but they can only be used as static", nonStaticField.Name);
            }
        }
예제 #13
0
        /// <summary>
        /// Subscribes all methods of the specified instance that are decorated with the <see cref="MessageRecipientAttribute"/>.
        /// </summary>
        /// <param name="instance">The instance to subscribe.</param>
        /// <param name="messageMediator">The message mediator. If <c>null</c>, the default will be used.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="instance"/> is <c>null</c>.</exception>
        /// <exception cref="NotSupportedException">The object has non-public methods decorated with the <see cref="MessageRecipientAttribute"/>, but the
        /// application is not written in .NET (but in SL, WP7 or WinRT).</exception>
        /// <exception cref="InvalidCastException">One of the methods cannot be casted to a valid message method.</exception>
        public static void SubscribeRecipient(object instance, IMessageMediator messageMediator = null)
        {
            Argument.IsNotNull("instance", instance);

            if (messageMediator == null)
            {
                var dependencyResolver = IoCConfiguration.DefaultDependencyResolver;
                messageMediator = dependencyResolver.Resolve <IMessageMediator>();
            }

            var mediator    = messageMediator;
            var methodInfos = instance.GetType().GetMethodsEx(BindingFlagsHelper.GetFinalBindingFlags(true, false));

            foreach (var methodInfo in methodInfos)
            {
                var customAttributes = methodInfo.GetCustomAttributesEx(typeof(MessageRecipientAttribute), true);

                foreach (var customAttribute in customAttributes)
                {
                    var attribute      = (MessageRecipientAttribute)customAttribute;
                    var parameterInfos = methodInfo.GetParameters();

                    Type actionType;
                    Type actionParameterType;

                    switch (parameterInfos.Length)
                    {
                    case 0:
                        actionType          = typeof(Action <object>);
                        actionParameterType = typeof(object);
                        break;

                    case 1:
                        actionType          = typeof(Action <>).MakeGenericType(parameterInfos[0].ParameterType);
                        actionParameterType = parameterInfos[0].ParameterType;
                        break;

                    default:
                        var error = string.Format("Cannot cast '{0}' to Action or Action<T> delegate type.", methodInfo.Name);
                        Log.Error(error);
                        throw new InvalidCastException(error);
                    }

                    var tag    = attribute.Tag;
                    var action = DelegateHelper.CreateDelegate(actionType, instance, methodInfo);

                    var registerMethod = mediator.GetType().GetMethodEx("Register").MakeGenericMethod(actionParameterType);
                    registerMethod.Invoke(mediator, new[] { instance, action, tag });
                }
            }
        }
예제 #14
0
파일: MefHelper.cs 프로젝트: ziez/Catel
        /// <summary>
        /// Gets the exports from key.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="key">The key.</param>
        /// <returns>
        /// An enumeration of exports.
        /// </returns>
        /// <exception cref="ArgumentNullException">The <paramref name="container"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">The <paramref name="key"/> is <c>null</c>.</exception>
        private IEnumerable <object> GetExportsFromKey(object container, string key)
        {
            Argument.IsNotNull("container", container);
            Argument.IsNotNull("key", key);

            // Retrieve GetExports<T>(string contractName)
            var methods = container.GetType().GetMethodsEx(BindingFlagsHelper.GetFinalBindingFlags(false, true));
            var getExportsMethodInfo = methods.Where(method => method.Name == "GetExports").
                                       Where(method => method.GetGenericArguments().Count() == 1).
                                       Where(method => method.GetParameters().Count() == 1).FirstOrDefault();
            var genericMethodInfo = getExportsMethodInfo.MakeGenericMethod(new[] { typeof(object) });

            return(((IEnumerable)genericMethodInfo.Invoke(container, new object[] { key })).Cast <object>());
        }
예제 #15
0
        /// <summary>
        /// Initializes the default values.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="obj"/> is <c>null</c>.</exception>
        private void InitializeDefaultValues(object obj)
        {
            Argument.IsNotNull("obj", obj);

            var properties = obj.GetType().GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, false));

            foreach (var property in properties)
            {
                if (!ShouldPropertyBeIgnored(obj, property.Name))
                {
                    _previousPropertyValues[property.Name] = PropertyHelper.GetPropertyValue(obj, property.Name);
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Finds the properties that represent a <see cref="PropertyData"/>.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The list of <see cref="PropertyData"/> elements found as properties.</returns>
        /// <exception cref="InvalidOperationException">One ore more properties are not declared correctly.</exception>
        private static IEnumerable <PropertyData> FindCatelProperties(Type type)
        {
            // Properties - safety checks for non-static properties
            var nonStaticProperties = (from property in type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true))
                                       where property.PropertyType == typeof(PropertyData)
                                       select property).ToList();

            foreach (var nonStaticProperty in nonStaticProperties)
            {
                string error = string.Format("The property '{0}' of type 'PropertyData' declared as instance, but they can only be used as static", nonStaticProperty.Name);

                Log.Error(error);
                throw new InvalidOperationException(error);
            }

            // Properties - safety checks for non-public fields
            var nonPublicProperties = (from property in type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, true))
                                       where property.PropertyType == typeof(PropertyData) && !property.CanRead
                                       select property).ToList();

            foreach (var nonPublicProperty in nonPublicProperties)
            {
                string error = string.Format("The property '{0}' of type 'PropertyData' declared as non-public, but they can only be used as public", nonPublicProperty.Name);

                Log.Error(error);
                throw new InvalidOperationException(error);
            }

            // Properties - actual addition
            var foundProperties = new List <PropertyData>();

            var properties = new List <PropertyInfo>();

            properties.AddRange(type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, false)));
            foreach (var property in properties)
            {
                if (property.PropertyType == typeof(PropertyData))
                {
                    var propertyValue = property.GetValue(null, null) as PropertyData;
                    if (propertyValue != null)
                    {
                        foundProperties.Add(propertyValue);
                    }
                }
            }

            return(foundProperties);
        }
예제 #17
0
            /// <summary>
            /// Initializes a new instance of the <see cref="EventTarget"/> class.
            /// </summary>
            /// <param name="associatedObject">The associated object.</param>
            /// <param name="eventTarget">The event target as string representation.</param>
            /// <remarks>
            /// If the parsing fails, no exception will be thrown but the <see cref="ControlName"/>
            /// and <see cref="EventName"/> will remain empty.
            /// </remarks>
            /// <exception cref="ArgumentNullException">The <paramref name="associatedObject"/> is <c>null</c>.</exception>
            /// <exception cref="ArgumentException">The <paramref name="eventTarget"/> is <c>null</c> or whitespace.</exception>
            /// <exception cref="InvalidOperationException">The <paramref name="associatedObject"/> is not yet loaded.</exception>
            public EventTarget(FrameworkElement associatedObject, string eventTarget)
            {
                Argument.IsNotNull("associatedObject", associatedObject);
                Argument.IsNotNullOrWhitespace("eventTarget", eventTarget);

#if NET
                if (!associatedObject.IsLoaded)
                {
                    throw new InvalidOperationException("The associated object is not yet loaded, which is required");
                }
#endif

                _associatedObject = associatedObject;
                ControlName       = string.Empty;
                EventName         = string.Empty;

                int dotIndex = eventTarget.IndexOf('.');
                if (dotIndex == -1)
                {
                    ControlName = eventTarget;
                    EventName   = "Click";
                }
                else
                {
                    ControlName = eventTarget.Substring(0, dotIndex);
                    EventName   = eventTarget.Substring(dotIndex + 1, eventTarget.Length - dotIndex - 1);
                }

                _target = _associatedObject.FindName(ControlName);
                if (_target == null)
                {
                    throw new InvalidOperationException(string.Format("'{0}' resulted in control name '{1}', which cannot be found on the associated object",
                                                                      eventTarget, ControlName));
                }

                _eventInfo = _target.GetType().GetEventEx(EventName);
                if (_eventInfo == null)
                {
                    throw new InvalidOperationException(string.Format("'{0}' resulted in event name '{1}', which cannot be found on target '{2}'",
                                                                      eventTarget, EventName, ControlName));
                }

                var methodInfo        = GetType().GetMethodEx("OnEvent", BindingFlagsHelper.GetFinalBindingFlags(true, false));
                var boundEventHandler = methodInfo.MakeGenericMethod(new[] { _eventInfo.EventHandlerType.GetMethodEx("Invoke").GetParameters()[1].ParameterType });

                _delegate = DelegateHelper.CreateDelegate(_eventInfo.EventHandlerType, this, boundEventHandler);
                _eventInfo.AddEventHandler(_target, _delegate);
            }
예제 #18
0
        /// <summary>
        /// Initializes the XML property mappings.
        /// </summary>
        /// <param name="type">The type for which to initialize the xml mappings.</param>
        private void InitializeXmlPropertyMappings(Type type)
        {
            if (_xmlNameToPropertyNameMappings.ContainsKey(type))
            {
                return;
            }

            lock (_xmlMappingsLock)
            {
                _xmlNameToPropertyNameMappings.Add(type, new Dictionary <string, string>());
                _xmlPropertyNameToXmlNameMappings.Add(type, new Dictionary <string, string>());

                var catelTypeInfo = _propertyDataManager.GetCatelTypeInfo(type);
                foreach (var propertyData in catelTypeInfo.GetCatelProperties())
                {
                    var propertyInfo = type.GetPropertyEx(propertyData.Key, BindingFlagsHelper.GetFinalBindingFlags(true, false));
                    if (propertyInfo == null)
                    {
                        // Dynamic property, not mapped (always fixed)
                        continue;
                    }

                    // 1st, check if XmlIgnore is used
                    if (AttributeHelper.IsDecoratedWithAttribute <XmlIgnoreAttribute>(propertyInfo))
                    {
                        continue;
                    }

                    // 2nd, check if XmlAttribute is used
                    XmlAttributeAttribute xmlAttributeAttribute = null;
                    AttributeHelper.TryGetAttribute(propertyInfo, out xmlAttributeAttribute);
                    if (InitializeXmlAttributeAttribute(type, xmlAttributeAttribute, propertyData.Key))
                    {
                        continue;
                    }

                    // 3rd, check if XmlElement is used
                    XmlElementAttribute xmlElementAttribute = null;
                    AttributeHelper.TryGetAttribute(propertyInfo, out xmlElementAttribute);
                    if (InitializeXmlElementAttribute(type, xmlElementAttribute, propertyData.Key))
                    {
                        continue;
                    }
                }
            }
        }
예제 #19
0
        /// <summary>
        /// Creates the dynamic closed delegate.
        /// </summary>
        /// <param name="eventHandlerType">Type of the event handler.</param>
        /// <returns>A dynamically created closed delegate.</returns>
        private Delegate CreateDynamicHandlerDelegate(Type eventHandlerType)
        {
            var handler = new DynamicMethod("DynamicEventHandler", null, GetDelegateParameterTypes(eventHandlerType));

            ILGenerator ilgen = handler.GetILGenerator();

            var handlerMethodInfo = GetType().GetMethodEx("OnEvent", BindingFlagsHelper.GetFinalBindingFlags(false, false));

            // this.OnTargetWindowClosed
            ilgen.Emit(OpCodes.Ldsfld, typeof(DynamicEventListener).GetFieldEx("Instances", BindingFlagsHelper.GetFinalBindingFlags(false, true)));
            ilgen.Emit(OpCodes.Ldc_I4, UniqueIdentifier);
            ilgen.Emit(OpCodes.Call, typeof(HandlerDictionary).GetMethodEx("Get", BindingFlagsHelper.GetFinalBindingFlags(true, false)));
            ilgen.Emit(OpCodes.Call, handlerMethodInfo);
            ilgen.Emit(OpCodes.Ret);

            return(handler.CreateDelegate(eventHandlerType));
        }
예제 #20
0
        /// <summary>
        /// Ensures that the dependency properties of the specified <see cref="FrameworkElement"/> are in the cache.
        /// </summary>
        /// <param name="frameworkElement">The framework element.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="frameworkElement"/> is <c>null</c>.</exception>
        private static void EnsureItemInCache(this FrameworkElement frameworkElement)
        {
            Argument.IsNotNull("frameworkElement", frameworkElement);

            var type = frameworkElement.GetType();

            if (_cacheByParentType.ContainsKey(type))
            {
                return;
            }

            var properties = new List <DependencyPropertyInfo>();

            var parentType = type;
            var fields     = parentType.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, true));

            foreach (var field in fields)
            {
                if (typeof(DependencyProperty).IsAssignableFromEx(field.FieldType))
                {
                    var names = field.ToString().Split(new[] { ' ' });
                    var name  = names[names.Length - 1];

                    int propertyPostfixIndex = name.LastIndexOf("Property");
                    if (propertyPostfixIndex != -1)
                    {
                        name = name.Substring(0, propertyPostfixIndex);
                    }

                    if (string.Equals(name, "__Direct") || string.Equals(name, "DirectDependency"))
                    {
                        continue;
                    }

                    var dependencyProperty = (DependencyProperty)field.GetValue(frameworkElement);
                    properties.Add(new DependencyPropertyInfo(dependencyProperty, name));

                    var propertyKey = GetDependencyPropertyCacheKey(frameworkElement, name);
                    _cacheByPropertyName[propertyKey] = dependencyProperty;
                    _cacheByDependencyProperty[dependencyProperty] = name;
                }
            }

            _cacheByParentType[type] = properties;
        }
예제 #21
0
        /// <summary>
        /// Modifies the source data before passing it to the target for display in the UI.
        /// </summary>
        /// <param name="value">The source data being passed to the target.</param>
        /// <param name="targetType">The <see cref="T:System.Type" /> of data expected by the target dependency property.</param>
        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
        /// <returns>The value to be passed to the target dependency property.</returns>
        protected override object Convert(object value, Type targetType, object parameter)
        {
            var methodName = parameter as string;

            if (value == null || methodName == null)
            {
                return(value);
            }

            var methodInfo = value.GetType().GetMethodEx(methodName, new Type[0], BindingFlagsHelper.GetFinalBindingFlags(true, true));

            if (methodInfo == null)
            {
                return(value);
            }

            return(methodInfo.Invoke(value, new object[0]));
        }
예제 #22
0
        /// <summary>
        /// Modifies the source data before passing it to the target for display in the UI.
        /// </summary>
        /// <param name="value">The source data being passed to the target.</param>
        /// <param name="targetType">The <see cref="T:System.Type" /> of data expected by the target dependency property.</param>
        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
        /// <returns>The value to be passed to the target dependency property.</returns>
        protected override object Convert(object value, Type targetType, object parameter)
        {
            var methodName = parameter as string;

            if (value is null || methodName is null)
            {
                return(value);
            }

            var bindingFlags = BindingFlagsHelper.GetFinalBindingFlags(true, true);
            var methodInfo   = value.GetType().GetMethodEx(methodName, ArrayShim.Empty <Type>(), bindingFlags);

            if (methodInfo is null)
            {
                return(value);
            }

            return(methodInfo.Invoke(value, ArrayShim.Empty <object>()));
        }
예제 #23
0
        /// <summary>
        ///     The get constructor ex.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="types">The types.</param>
        /// <returns>ConstructorInfo.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="type" /> is <c>null</c>.</exception>
        /// <exception cref="System.ArgumentNullException">The <paramref name="types" /> is <c>null</c>.</exception>
        public static ConstructorInfo GetConstructorEx(this Type type, Type[] types)
        {
            Argument.IsNotNull(nameof(type), type);
            Argument.IsNotNull(nameof(types), types);

#if ENABLE_CACHE
            var cacheKey = new ReflectionCacheKey(type, ReflectionTypes.Constructor, BindingFlags.Default, types);
#if NETFX_CORE || PCL
            return(_constructorCache.GetFromCacheOrFetch(cacheKey, () => type.GetTypeInfo().GetConstructor(types, BindingFlagsHelper.GetFinalBindingFlags(false, false))));
#else
            return(_constructorCache.GetFromCacheOrFetch(cacheKey, () => type.GetConstructor(types)));
#endif
#else
#if NETFX_CORE || PCL
            return(type.GetTypeInfo().GetConstructor(types, BindingFlagsHelper.GetFinalBindingFlags(false, false)));
#else
            return(type.GetConstructor(types));
#endif
#endif
        }
예제 #24
0
        /// <summary>
        /// Subscribes to the event.
        /// </summary>
        private void SubscribeToEvent()
        {
            if (_isSubscribed)
            {
                return;
            }

            lock (Instances)
            {
                Instances.Add(UniqueIdentifier, this);
            }

            _eventInfo = _eventInstanceType.GetEventEx(EventName, BindingFlagsHelper.GetFinalBindingFlags(true, false));
            if (_eventInfo == null)
            {
                throw Log.ErrorAndCreateException <NotSupportedException>("Cannot find the '{0}' event, implement the '{0}' event on '{1}'", EventName, _eventInstanceType.Name);
            }

            _handler = CreateDynamicHandlerDelegate(_eventInfo.EventHandlerType);
            _eventInfo.AddEventHandler(_eventInstance, _handler);
        }
예제 #25
0
파일: MefHelper.cs 프로젝트: ziez/Catel
        /// <summary>
        /// Registers a specific instance for the specified interface.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="interfaceType">Type of the interface.</param>
        /// <param name="implementingInstance">The implementing instance.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="container"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">If <paramref name="interfaceType"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">If <paramref name="implementingInstance"/> is <c>null</c>.</exception>
        /// <exception cref="NotSupportedException">If <paramref name="container"/> is not a MEF IoC container.</exception>
        public override void RegisterInstance(object container, Type interfaceType, object implementingInstance)
        {
            Argument.IsNotNull("container", container);
            Argument.IsNotNull("interfaceType", interfaceType);
            Argument.IsNotNull("implementingInstance", implementingInstance);

            if (!IsValidContainer(container))
            {
                throw new NotSupportedException("Only MEF containers are supported");
            }

            var attributedModelServicesType = GetContainerType("System.ComponentModel.Composition.AttributedModelServices", container);

            // Retrieve ComposeExportedValue<T>(this CompositionContainer container, T exportedValue)
            var methods = attributedModelServicesType.GetMethodsEx(BindingFlagsHelper.GetFinalBindingFlags(false, true));
            var composeExportedValueMethodInfo = methods.Where(method => method.Name == "ComposeExportedValue").
                                                 Where(method => method.GetGenericArguments().Count() == 1).
                                                 Where(method => method.GetParameters().Count() == 2).FirstOrDefault();
            var genericComposeExportedValue = composeExportedValueMethodInfo.MakeGenericMethod(new[] { interfaceType });

            genericComposeExportedValue.Invoke(null, new[] { container, implementingInstance });
        }
예제 #26
0
        /// <summary>
        /// Gets the dependency property with the specified property name.
        /// </summary>
        /// <param name="dependencyPropertyName">Name of the property.</param>
        /// <returns>The <see cref="DependencyProperty"/> or <c>null</c> if the dependency property is not found.</returns>
        private DependencyProperty GetDependencyProperty(string dependencyPropertyName)
        {
            DependencyProperty property = null;

            var bindingFlags = BindingFlagsHelper.GetFinalBindingFlags(true, true);
            var fieldInfo    = AssociatedObject.GetType().GetFieldEx(dependencyPropertyName, bindingFlags);

            if (fieldInfo != null)
            {
                property = fieldInfo.GetValue(null) as DependencyProperty;
            }

            if (property == null)
            {
                Log.Error("Failed to retrieve dependency property '{0}' from object '{1}'", dependencyPropertyName, AssociatedObject.GetType());
            }
            else
            {
                Log.Debug("Retrieved dependency property '{0}' from object '{1}'", dependencyPropertyName, AssociatedObject.GetType());
            }

            return(property);
        }
예제 #27
0
        /// <summary>
        /// Ensures that the dependency properties of the specified <see cref="FrameworkElement"/> are in the cache.
        /// </summary>
        /// <param name="viewType">The view type.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="viewType"/> is <c>null</c>.</exception>
        private static void EnsureItemInCache(this Type viewType)
        {
            if (_cacheByParentType.ContainsKey(viewType))
            {
                return;
            }

            var properties = new List <DependencyPropertyInfo>();

            var bindingFlags = BindingFlagsHelper.GetFinalBindingFlags(true, true);

            var typeMembers = new List <MemberInfo>();

            typeMembers.AddRange(viewType.GetFieldsEx(bindingFlags));
            typeMembers.AddRange(viewType.GetPropertiesEx(bindingFlags));

            foreach (var member in typeMembers)
            {
                try
                {
                    var fieldInfo    = member as FieldInfo;
                    var propertyInfo = member as PropertyInfo;

                    if (fieldInfo != null)
                    {
                        if (!typeof(DependencyProperty).IsAssignableFromEx(fieldInfo.FieldType))
                        {
                            continue;
                        }
                    }
                    else if (propertyInfo != null)
                    {
                        if (!typeof(DependencyProperty).IsAssignableFromEx(propertyInfo.PropertyType))
                        {
                            continue;
                        }
                    }

                    string name = member.Name;

                    int propertyPostfixIndex = name.LastIndexOf("Property", StringComparison.Ordinal);
                    if (propertyPostfixIndex != -1)
                    {
                        name = name.Substring(0, propertyPostfixIndex);
                    }

                    if (string.Equals(name, "__Direct") || string.Equals(name, "DirectDependency"))
                    {
                        continue;
                    }

                    DependencyProperty dependencyProperty;
                    if (fieldInfo != null)
                    {
                        var fieldValue = fieldInfo.GetValue(null);
                        dependencyProperty = fieldValue as DependencyProperty;
                    }
                    else if (propertyInfo != null)
                    {
#if NETFX_CORE
                        var propertyValue = propertyInfo.GetValue(null);
                        dependencyProperty = propertyValue as DependencyProperty;
#else
                        var propertyValue = propertyInfo.GetValue(null, null);
                        dependencyProperty = propertyValue as DependencyProperty;
#endif
                    }
                    else
                    {
                        continue;
                    }

                    if (dependencyProperty == null)
                    {
                        continue;
                    }

                    properties.Add(new DependencyPropertyInfo(dependencyProperty, name));

                    string propertyKey = GetDependencyPropertyCacheKey(viewType, name);
                    _cacheByPropertyName[propertyKey] = dependencyProperty;
                    _cacheByDependencyProperty[dependencyProperty] = name;
                }
                catch (Exception ex)
                {
                    Log.Warning(ex, $"Failed to enumerate member '{member.Name}' as dependency property");
                }
            }

            _cacheByParentType[viewType] = properties;
        }
예제 #28
0
        /// <summary>
        /// Ensures that the dependency properties of the specified <see cref="FrameworkElement"/> are in the cache.
        /// </summary>
        /// <param name="frameworkElement">The framework element.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="frameworkElement"/> is <c>null</c>.</exception>
        private static void EnsureItemInCache(this FrameworkElement frameworkElement)
        {
            Argument.IsNotNull("frameworkElement", frameworkElement);

            var type = frameworkElement.GetType();

            if (_cacheByParentType.ContainsKey(type))
            {
                return;
            }

            var properties = new List <DependencyPropertyInfo>();

            var typeMembers = new List <MemberInfo>();

            typeMembers.AddRange(type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, true)));
            typeMembers.AddRange(type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, true)));

            foreach (MemberInfo member in typeMembers)
            {
                var fieldInfo    = member as FieldInfo;
                var propertyInfo = member as PropertyInfo;

                if (fieldInfo != null)
                {
                    if (!typeof(DependencyProperty).IsAssignableFromEx(fieldInfo.FieldType))
                    {
                        continue;
                    }
                }
                else if (propertyInfo != null)
                {
                    if (!typeof(DependencyProperty).IsAssignableFromEx(propertyInfo.PropertyType))
                    {
                        continue;
                    }
                }

                string name = member.Name;

                int propertyPostfixIndex = name.LastIndexOf("Property", StringComparison.Ordinal);
                if (propertyPostfixIndex != -1)
                {
                    name = name.Substring(0, propertyPostfixIndex);
                }

                if (string.Equals(name, "__Direct") || string.Equals(name, "DirectDependency"))
                {
                    continue;
                }

                DependencyProperty dependencyProperty;
                if (fieldInfo != null)
                {
                    dependencyProperty = (DependencyProperty)fieldInfo.GetValue(frameworkElement);
                }
                else if (propertyInfo != null)
                {
#if NETFX_CORE
                    dependencyProperty = (DependencyProperty)propertyInfo.GetValue(frameworkElement);
#else
                    dependencyProperty = (DependencyProperty)propertyInfo.GetValue(frameworkElement, null);
#endif
                }
                else
                {
                    continue;
                }

                properties.Add(new DependencyPropertyInfo(dependencyProperty, name));

                string propertyKey = GetDependencyPropertyCacheKey(frameworkElement, name);
                _cacheByPropertyName[propertyKey] = dependencyProperty;
                _cacheByDependencyProperty[dependencyProperty] = name;
            }

            _cacheByParentType[type] = properties;
        }
예제 #29
0
        /// <summary>
        /// Called when the event occurs.
        /// </summary>
// ReSharper disable UnusedMember.Global
        public void OnEvent()
// ReSharper restore UnusedMember.Global
        {
            EventOccurred.SafeInvoke(this);

            if (_handlerInstance != null)
            {
                var handlerMethodInfo = _handlerInstance.GetType().GetMethodEx(HandlerName, BindingFlagsHelper.GetFinalBindingFlags(true, false));
                if (handlerMethodInfo == null)
                {
                    throw Log.ErrorAndCreateException <NotSupportedException>("Cannot find the '{0}' method, implement the '{0}' method on '{1}'", EventName, _handlerInstance.GetType().Name);
                }

                handlerMethodInfo.Invoke(_handlerInstance, null);
            }
        }
예제 #30
0
            public void ReturnsInstanceMethods()
            {
                var methods = typeof(DerivedClass).GetMethodsEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true), true);

                Assert.IsTrue(methods.Any(x => x.Name == "Method2"));
            }