예제 #1
0
        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);
            }

            var implementation = typeBuilder.CreateType();
            var creator        = (Func <DictionaryAdapterInstance, IDictionaryAdapter>)Delegate.CreateDelegate
                                 (
                typeof(Func <DictionaryAdapterInstance, IDictionaryAdapter>),
                implementation,
                "__Create"
                                 );

            var meta = new DictionaryAdapterMeta(type, implementation, typeBehaviors,
                                                 initializers.MetaInitializers.ToArray(), initializers.Initializers.ToArray(),
                                                 propertyMap, this, creator);

            const BindingFlags metaBindings = BindingFlags.Public | BindingFlags.Static | BindingFlags.SetField;

            implementation.InvokeMember("__meta", metaBindings, null, null, new[] { meta });
            return(meta);
        }
예제 #2
0
        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 => (bool?)b.Fetch).FirstOrDefault().GetValueOrDefault();

//#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);

                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);
                }

//#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);
            });

            return(propertyMap);
        }