コード例 #1
0
ファイル: Enum.cs プロジェクト: jjmyrup/Catel
        /// <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());
        }
コード例 #2
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);
        }
コード例 #3
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
        }
コード例 #4
0
ファイル: CatelTypeInfo.cs プロジェクト: lixingx86/Catel
        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);
            }
        }
コード例 #5
0
ファイル: CatelTypeInfo.cs プロジェクト: lixingx86/Catel
        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);
            }
        }
コード例 #6
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 });
                }
            }
        }
コード例 #7
0
ファイル: ObjectObserver.cs プロジェクト: yicong/Catel
        /// <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);
                }
            }
        }
コード例 #8
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>());
        }
コード例 #9
0
ファイル: WindowBehavior.cs プロジェクト: yicong/Catel
            /// <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);
            }
コード例 #10
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);
        }
コード例 #11
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;
                    }
                }
            }
        }
コード例 #12
0
ファイル: DynamicEventListener.cs プロジェクト: wqhenry/Catel
        /// <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));
        }
コード例 #13
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;
        }
コード例 #14
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]));
        }
コード例 #15
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>()));
        }
コード例 #16
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
        }
コード例 #17
0
ファイル: DynamicEventListener.cs プロジェクト: wqhenry/Catel
        /// <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);
        }
コード例 #18
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 });
        }
コード例 #19
0
ファイル: DelayBindingUpdate.cs プロジェクト: wqhenry/Catel
        /// <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);
        }
コード例 #20
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;
        }
コード例 #21
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)
 {
     return((from property in type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true))
             where property.PropertyType != typeof(PropertyData)
             select property).ToList());
 }
コード例 #22
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;
        }
コード例 #23
0
ファイル: DynamicEventListener.cs プロジェクト: wqhenry/Catel
        /// <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);
            }
        }
コード例 #24
0
 /// <summary>
 /// Gets the <see cref="PropertyInfo"/> for the specified property.
 /// </summary>
 /// <param name="property">The name of the property.</param>
 /// <returns><see cref="PropertyInfo"/> or <c>null</c> if no property info is found.</returns>
 protected PropertyInfo GetPropertyInfo(string property)
 {
     return(GetType().GetPropertyEx(property, BindingFlagsHelper.GetFinalBindingFlags(true, false)));
 }
コード例 #25
0
            public void ReturnsInstanceMethods()
            {
                var methods = typeof(DerivedClass).GetMethodsEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true), true);

                Assert.IsTrue(methods.Any(x => x.Name == "Method2"));
            }
コード例 #26
0
            public void ReturnsInstanceProperties()
            {
                var properties = typeof(DerivedClass).GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true), true);

                Assert.IsTrue(properties.Any(x => x.Name == "Property2"));
            }
コード例 #27
0
            public void ReturnsStaticFields()
            {
                var fields = typeof(DerivedClass).GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, true), true);

                Assert.IsTrue(fields.Any(x => x.Name == "field1"));
            }
コード例 #28
0
        /// <summary>
        /// Gets the known types inside the specific type.
        /// </summary>
        /// <param name="type">The type to retrieve the known types for.</param>
        /// <param name="knownTypeList">The known type list.</param>
        /// <param name="alreadyCheckedTypes">The already checked types.</param>
        /// <returns>
        /// Array of <see cref="Type"/> that are found in the object type.
        /// </returns>
        /// <exception cref="ArgumentNullException">The <paramref name="knownTypeList"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">The <paramref name="alreadyCheckedTypes"/> is <c>null</c>.</exception>
        private static Type[] GetKnownTypes(Type type, HashSet <Type> knownTypeList, HashSet <Type> alreadyCheckedTypes)
        {
            if (!ShouldTypeBeHandled(type, knownTypeList, alreadyCheckedTypes))
            {
                return(knownTypeList.ToArray());
            }

            Log.Debug("Getting known types for '{0}'", type.FullName);

            // If this is an interface, HOUSTON, WE HAVE A PROBLEM
            if (type.IsInterfaceEx())
            {
                if (!alreadyCheckedTypes.Contains(type))
                {
                    Log.Debug("Type is an interface, checking all types deriving from this interface");

                    // Don't check this interface again in children checks
                    alreadyCheckedTypes.Add(type);

                    // Interfaces are not a type, and in fact a LOT of types can be added (in fact every object implementing the interface). For
                    // serialization, this is not a problem (we know the exact type), but for deserialization this IS an issue because we should
                    // expect EVERY type that implements the type in the whole AppDomain.
                    //
                    // This is huge performance hit, but it's the cost for dynamic easy on-the-fly serialization in WPF and Silverlight. Luckily
                    // we already implemented caching.
                    var typesDerivingFromInterface = TypeCache.GetTypes(t => t.IsAssignableFromEx(type));
                    foreach (var typeDerivingFromInterface in typesDerivingFromInterface)
                    {
                        if (typeDerivingFromInterface != type)
                        {
                            GetKnownTypes(typeDerivingFromInterface, knownTypeList, alreadyCheckedTypes);
                        }
                    }

                    Log.Debug("Finished checking all types deriving from this interface");
                }

                // The interface itself is ignored
                return(knownTypeList.ToArray());
            }

            if (IsSpecialCollectionType(type) && !type.IsInterfaceEx())
            {
                Log.Debug("Type is a special collection type, adding it to the array of known types");

                AddTypeToKnownTypesIfSerializable(knownTypeList, type);
            }

            // Fix generics
            if (type.FullName.StartsWith("System."))
            {
                Type[] genericArguments = type.GetTypeInfo().GenericTypeArguments;
                foreach (var genericArgument in genericArguments)
                {
                    Log.Debug("Retrieving known types for generic argument '{0}' of '{1}'", genericArgument.FullName, type.FullName);

                    GetKnownTypes(genericArgument, knownTypeList, alreadyCheckedTypes);
                }

                return(knownTypeList.ToArray());
            }

            if (!AddTypeToKnownTypesIfSerializable(knownTypeList, type))
            {
                alreadyCheckedTypes.Add(type);
            }

            // Fields
            var fields = type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(false, false));

            foreach (var field in fields)
            {
                Log.Debug("Getting known types for field '{0}' of '{1}'", field.Name, type.FullName);

                var fieldType = field.FieldType;
                if (fieldType.FullName != null)
                {
                    GetKnownTypes(fieldType, knownTypeList, alreadyCheckedTypes);
                }
                else
                {
                    alreadyCheckedTypes.Add(fieldType);
                }
            }

            // Properties
            var properties = type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(false, false));

            foreach (var property in properties)
            {
                Log.Debug("Getting known types for property '{0}' of '{1}'", property.Name, type.FullName);

                var propertyType = property.PropertyType;
                if (propertyType.FullName != null)
                {
                    GetKnownTypes(propertyType, knownTypeList, alreadyCheckedTypes);
                }
                else
                {
                    alreadyCheckedTypes.Add(propertyType);
                }
            }

            // If this isn't the base type, check that as well
            var baseType = type.GetTypeInfo().BaseType;

            if (baseType != null)
            {
                Log.Debug("Checking base type of '{0}' for known types", type.FullName);

                if (baseType.FullName != null)
                {
                    GetKnownTypes(baseType, knownTypeList, alreadyCheckedTypes);
                }
                else
                {
                    alreadyCheckedTypes.Add(baseType);
                }
            }

            // Last but not least, check if the type is decorated with KnownTypeAttributes
            var knowTypesByAttributes = GetKnownTypesViaAttributes(type);

            if (knowTypesByAttributes.Length > 0)
            {
                Log.Debug("Found {0} additional known types for type '{1}'", knowTypesByAttributes.Length, type.FullName);

                foreach (var knownTypeByAttribute in knowTypesByAttributes)
                {
                    var attributeType = knownTypeByAttribute;
                    if (attributeType.FullName != null)
                    {
                        GetKnownTypes(knownTypeByAttribute, knownTypeList, alreadyCheckedTypes);
                    }
                    else
                    {
                        alreadyCheckedTypes.Add(attributeType);
                    }
                }
            }

            return(knownTypeList.ToArray());
        }
コード例 #29
0
        /// <summary>
        /// Gets the known types for a specific object instance.
        /// </summary>
        /// <param name="obj">The object to retrieve the known types for.</param>
        /// <param name="knownTypeList">The known type list.</param>
        /// <param name="alreadyCheckedTypes">The already checked types.</param>
        /// <returns>
        /// Array of <see cref="Type"/> that are found in the object instance.
        /// </returns>
        /// <exception cref="ArgumentNullException">The <paramref name="knownTypeList"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">The <paramref name="alreadyCheckedTypes"/> is <c>null</c>.</exception>
        private static Type[] GetKnownTypesForInstance(object obj, HashSet <Type> knownTypeList, HashSet <Type> alreadyCheckedTypes)
        {
            Argument.IsNotNull("knownTypeList", knownTypeList);
            Argument.IsNotNull("alreadyCheckedTypes", alreadyCheckedTypes);

            if (obj == null)
            {
                return(knownTypeList.ToArray());
            }

            Type objectType = obj.GetType();

            if (!ShouldTypeBeHandled(objectType, knownTypeList, alreadyCheckedTypes))
            {
                return(knownTypeList.ToArray());
            }

            Log.Debug("Getting known types for instance of '{0}'", objectType.FullName);

            GetKnownTypes(objectType, knownTypeList, alreadyCheckedTypes);

            if (objectType.FullName == null)
            {
                alreadyCheckedTypes.Add(objectType);
                return(knownTypeList.ToArray());
            }

            // Collections might contain interface types, so if this is an IEnumerable, we need to loop all the instances (performance warning!)
            var objAsIEnumerable = obj as IEnumerable;

            if ((objAsIEnumerable != null) && (!(obj is string)))
            {
                foreach (object item in objAsIEnumerable)
                {
                    if (item != null)
                    {
                        GetKnownTypesForInstance(item, knownTypeList, alreadyCheckedTypes);
                    }
                }
            }

            if (objectType == typeof(List <KeyValuePair <string, object> >))
            {
                foreach (var keyValuePair in ((List <KeyValuePair <string, object> >)obj))
                {
                    GetKnownTypesForInstance(keyValuePair.Value, knownTypeList, alreadyCheckedTypes);
                }
            }
            else if (objectType == typeof(List <PropertyValue>))
            {
                foreach (var propertyValue in ((List <PropertyValue>)obj))
                {
                    GetKnownTypesForInstance(propertyValue.Value, knownTypeList, alreadyCheckedTypes);
                }
            }
            // Generic collections are special in Silverlight and WP7 (WHY?!)
            else if (IsSpecialCollectionType(objectType) && !objectType.IsInterfaceEx())
            {
                AddTypeToKnownTypesIfSerializable(knownTypeList, objectType);
            }
            else if (!objectType.FullName.StartsWith("System."))
            {
                var fields = objectType.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(false, false));
                foreach (var field in fields)
                {
                    try
                    {
                        object value = field.GetValue(obj);
                        GetKnownTypes(value == null ? field.FieldType : value.GetType(), knownTypeList, alreadyCheckedTypes);
                    }
                    catch (Exception)
                    {
                        Log.Warning("Failed to get value for field '{0}' of type '{1}'", field.Name, objectType.Name);
                    }
                }

                var properties = objectType.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(false, false));
                foreach (var property in properties)
                {
                    try
                    {
                        object value = property.GetValue(obj, null);
                        GetKnownTypes(value == null ? property.PropertyType : value.GetType(), knownTypeList, alreadyCheckedTypes);
                    }
                    catch (Exception)
                    {
                        Log.Warning("Failed to get value for property '{0}' of type '{1}'", property.Name, objectType.Name);
                    }
                }
            }

            return(knownTypeList.ToArray());
        }
コード例 #30
0
ファイル: MefHelper.cs プロジェクト: ziez/Catel
        /// <summary>
        /// Gets the key from interface, which is required for MEF.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="interfaceType">Type of the interface.</param>
        /// <returns>The key based on the interface.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="interfaceType"/> is <c>null</c>.</exception>
        private string GetKeyFromInterface(object container, Type interfaceType)
        {
            Argument.IsNotNull("interfaceType", interfaceType);

            var attributedModelServicesType = GetContainerType("System.ComponentModel.Composition.AttributedModelServices", container);
            var getContractNameMethodInfo   = attributedModelServicesType.GetMethodEx("GetContractName", new[] { typeof(Type) }, BindingFlagsHelper.GetFinalBindingFlags(false, true));

            return((string)getContractNameMethodInfo.Invoke(null, new[] { interfaceType }));
        }