private DictionaryAdapterMeta CreateAdapterMeta(Type type, TypeBuilder typeBuilder, PropertyDescriptor descriptor) { var binding = FieldAttributes.Public | FieldAttributes.Static; var metaField = typeBuilder.DefineField("__meta", typeof(DictionaryAdapterMeta), binding); var constructor = CreateAdapterConstructor(typeBuilder); CreateAdapterFactoryMethod(typeBuilder, constructor); object[] typeBehaviors; var initializers = new PropertyDescriptor(); var propertyMap = GetPropertyDescriptors(type, initializers, out typeBehaviors); if (descriptor != null) { #if DOTNET40 initializers.AddBehaviors(descriptor.MetaInitializers); #else initializers.AddBehaviors(descriptor.MetaInitializers.Cast <IDictionaryBehavior>()); #endif typeBehaviors = typeBehaviors.Union(descriptor.Annotations).ToArray(); } CreateMetaProperty(typeBuilder, AdapterGetMeta, metaField); foreach (var property in propertyMap) { CreateAdapterProperty(typeBuilder, property.Value); } #if FEATURE_LEGACY_REFLECTION_API var implementation = typeBuilder.CreateType(); var creator = (Func <DictionaryAdapterInstance, IDictionaryAdapter>)Delegate.CreateDelegate ( typeof(Func <DictionaryAdapterInstance, IDictionaryAdapter>), implementation, "__Create" ); #else var implementation = typeBuilder.CreateTypeInfo().AsType(); var creator = (Func <DictionaryAdapterInstance, IDictionaryAdapter>)implementation .GetTypeInfo().GetDeclaredMethod("__Create") .CreateDelegate(typeof(Func <DictionaryAdapterInstance, IDictionaryAdapter>)); #endif var meta = new DictionaryAdapterMeta(type, implementation, typeBehaviors, initializers.MetaInitializers.ToArray(), initializers.Initializers.ToArray(), propertyMap, this, creator); #if FEATURE_LEGACY_REFLECTION_API const BindingFlags metaBindings = BindingFlags.Public | BindingFlags.Static | BindingFlags.SetField; implementation.InvokeMember("__meta", metaBindings, null, null, new[] { meta }); #else const BindingFlags metaBindings = BindingFlags.Public | BindingFlags.Static; var field = implementation.GetField("__meta", metaBindings); field.SetValue(implementation, meta); #endif return(meta); }
private static Dictionary <string, PropertyDescriptor> GetPropertyDescriptors(Type type, PropertyDescriptor initializers, out object[] typeBehaviors) { var propertyMap = new Dictionary <string, PropertyDescriptor>(); var interfaceBehaviors = typeBehaviors = ExpandBehaviors(InterfaceAttributeUtil.GetAttributes(type, true)).ToArray(); var defaultFetch = typeBehaviors.OfType <FetchAttribute>().Select(b => (bool?)b.Fetch).FirstOrDefault().GetValueOrDefault(); initializers.AddBehaviors(typeBehaviors.OfType <IDictionaryMetaInitializer>()) .AddBehaviors(typeBehaviors.OfType <IDictionaryInitializer>()); CollectProperties(type, (property, reflectedType) => { var propertyBehaviors = ExpandBehaviors(property.GetCustomAttributes(false)).ToArray(); var propertyDescriptor = new PropertyDescriptor(property, propertyBehaviors) .AddBehaviors(propertyBehaviors.OfType <IDictionaryBehavior>()) .AddBehaviors(interfaceBehaviors.OfType <IDictionaryBehavior>().Where(b => b is IDictionaryKeyBuilder == false)); var expandedBehaviors = ExpandBehaviors(InterfaceAttributeUtil .GetAttributes(reflectedType, true)) .OfType <IDictionaryKeyBuilder>(); propertyDescriptor = propertyDescriptor.AddBehaviors(expandedBehaviors); AddDefaultGetter(propertyDescriptor); var propertyFetch = propertyBehaviors.OfType <FetchAttribute>().Select(b => (bool?)b.Fetch).FirstOrDefault(); propertyDescriptor.IfExists = propertyBehaviors.OfType <IfExistsAttribute>().Any(); propertyDescriptor.Fetch = propertyFetch.GetValueOrDefault(defaultFetch); foreach (var descriptorInitializer in propertyDescriptor.Behaviors.OfType <IPropertyDescriptorInitializer>()) { descriptorInitializer.Initialize(propertyDescriptor, propertyBehaviors); } initializers.AddBehaviors(propertyBehaviors.OfType <IDictionaryMetaInitializer>()); PropertyDescriptor existingDescriptor; if (propertyMap.TryGetValue(property.Name, out existingDescriptor)) { var existingProperty = existingDescriptor.Property; if (existingProperty.PropertyType == property.PropertyType) { if (property.CanRead && property.CanWrite) { propertyMap[property.Name] = propertyDescriptor; } return; } } propertyMap.Add(property.Name, propertyDescriptor); }); return(propertyMap); }
private DictionaryAdapterMeta CreateAdapterMeta( Type type, TypeBuilder typeBuilder, PropertyDescriptor descriptor ) { var binding = FieldAttributes.Public | FieldAttributes.Static; var metaField = typeBuilder.DefineField( "__meta", typeof(DictionaryAdapterMeta), binding ); var constructor = CreateAdapterConstructor(typeBuilder); CreateAdapterFactoryMethod(typeBuilder, constructor); object[] typeBehaviors; var initializers = new PropertyDescriptor(); var propertyMap = GetPropertyDescriptors(type, initializers, out typeBehaviors); if (descriptor != null) { initializers.AddBehaviors(descriptor.MetaInitializers); typeBehaviors = typeBehaviors.Union(descriptor.Annotations).ToArray(); } CreateMetaProperty(typeBuilder, AdapterGetMeta, metaField); foreach (var property in propertyMap) { CreateAdapterProperty(typeBuilder, property.Value); } var implementation = typeBuilder.CreateTypeInfo(); var creator = (Func <DictionaryAdapterInstance, IDictionaryAdapter>)implementation .GetDeclaredMethod("__Create") .CreateDelegate(typeof(Func <DictionaryAdapterInstance, IDictionaryAdapter>)); var meta = new DictionaryAdapterMeta( type, implementation, typeBehaviors, initializers.MetaInitializers.ToArray(), initializers.Initializers.ToArray(), propertyMap, this, creator ); const BindingFlags metaBindings = BindingFlags.Public | BindingFlags.Static; var field = implementation.GetField("__meta", metaBindings); field.SetValue(implementation, meta); return(meta); }
private static Dictionary <String, PropertyDescriptor> GetPropertyDescriptors(Type type, PropertyDescriptor initializers, out object[] typeBehaviors) { var propertyMap = new Dictionary <String, PropertyDescriptor>(); var interfaceBehaviors = typeBehaviors = ExpandBehaviors(AttributesUtil.GetInterfaceAttributes(type)).ToArray(); var defaultFetch = typeBehaviors.OfType <FetchAttribute>().Select(b => b.Fetch).FirstOrDefault(); #if DOTNET40 initializers.AddBehaviors(typeBehaviors.OfType <IDictionaryMetaInitializer>()) .AddBehaviors(typeBehaviors.OfType <IDictionaryInitializer>()); #else initializers.AddBehaviors(typeBehaviors.OfType <IDictionaryMetaInitializer>().Cast <IDictionaryBehavior>()) .AddBehaviors(typeBehaviors.OfType <IDictionaryInitializer> ().Cast <IDictionaryBehavior>()); #endif CollectProperties(type, property => { var propertyBehaviors = ExpandBehaviors(AttributesUtil.GetAttributes <object>(property)).ToArray(); var propertyDescriptor = new PropertyDescriptor(property, propertyBehaviors) .AddBehaviors(propertyBehaviors.OfType <IDictionaryBehavior>()) .AddBehaviors(interfaceBehaviors.OfType <IDictionaryBehavior>().Where(b => b is IDictionaryKeyBuilder == false)) #if DOTNET40 .AddBehaviors(ExpandBehaviors(AttributesUtil .GetInterfaceAttributes(property.ReflectedType)) .OfType <IDictionaryKeyBuilder>()); #else .AddBehaviors(ExpandBehaviors(AttributesUtil .GetInterfaceAttributes(property.ReflectedType)) .OfType <IDictionaryKeyBuilder>() .Cast <IDictionaryBehavior>()); #endif AddDefaultGetter(propertyDescriptor); bool?propertyFetch = (from b in propertyBehaviors.OfType <FetchAttribute>() select b.Fetch).FirstOrDefault(); propertyDescriptor.IfExists = propertyBehaviors.OfType <IfExistsAttribute>().Any(); propertyDescriptor.Fetch = propertyFetch.GetValueOrDefault(defaultFetch); foreach (var descriptorInitializer in propertyDescriptor.Behaviors.OfType <IPropertyDescriptorInitializer>()) { descriptorInitializer.Initialize(propertyDescriptor, propertyBehaviors); } #if DOTNET40 initializers.AddBehaviors(propertyBehaviors.OfType <IDictionaryMetaInitializer>()); #else initializers.AddBehaviors(propertyBehaviors.OfType <IDictionaryMetaInitializer>().Cast <IDictionaryBehavior>()); #endif PropertyDescriptor existingDescriptor; if (propertyMap.TryGetValue(property.Name, out existingDescriptor)) { var existingProperty = existingDescriptor.Property; if (existingProperty.PropertyType == property.PropertyType) { if (property.CanRead && property.CanWrite) { propertyMap[property.Name] = propertyDescriptor; } return; } } propertyMap.Add(property.Name, propertyDescriptor); });