/// <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); }
/// <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)); }
/// <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); }
/// <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); }
/// <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()); }
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); } } } }
/// <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()); }
/// <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); }
/// <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 }
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); } }
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); } }
/// <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 }); } } }
/// <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>()); }
/// <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); } } }
/// <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); }
/// <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); }
/// <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; } } } }
/// <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)); }
/// <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; }
/// <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])); }
/// <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>())); }
/// <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 }
/// <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); }
/// <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 }); }
/// <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); }
/// <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; }
/// <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; }
/// <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); } }
public void ReturnsInstanceMethods() { var methods = typeof(DerivedClass).GetMethodsEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true), true); Assert.IsTrue(methods.Any(x => x.Name == "Method2")); }