OnDemandAttribute
                    public class OnDemandAttribute : DictionaryBehaviorAttribute, IDictionaryPropertyGetter, IDictionaryBehavior
                
                Support for on-demand value resolution.
            
                using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Castle.Components.DictionaryAdapter
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Interface, AllowMultiple = false)]
    public class OnDemandAttribute : DictionaryBehaviorAttribute, IDictionaryPropertyGetter, IDictionaryBehavior
    {
        public Type Type { get; set; }
        public object Value { get; set; }
        public OnDemandAttribute()
        {
        }
        public OnDemandAttribute(Type type)
        {
            if ((object)TypeExtensions.GetConstructor(type, Type.EmptyTypes) == null)
                throw new ArgumentException("On-demand values must have a parameterless constructor");
            Type = type;
        }
        public OnDemandAttribute(object value)
        {
            Value = value;
        }
        public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, object storedValue, PropertyDescriptor property, bool ifExists)
        {
            if (storedValue == null && !ifExists) {
                IValueInitializer initializer = null;
                if (Value != null)
                    storedValue = Value;
                else {
                    Type type = Type ?? GetInferredType(dictionaryAdapter, property, out initializer);
                    if (IsAcceptedType(type)) {
                        if (type.GetTypeInfo().get_IsInterface()) {
                            if (!property.IsDynamicProperty && storedValue == null)
                                storedValue = dictionaryAdapter.Create(property.PropertyType);
                        } else if (type.GetTypeInfo().get_IsArray()) {
                            storedValue = Array.CreateInstance(type.GetElementType(), 0);
                        } else if (storedValue == null) {
                            object[] parameters = null;
                            ConstructorInfo constructorInfo = null;
                            if (property.IsDynamicProperty) {
                                constructorInfo = (from <>h__TransparentIdentifier0 in (from ctor in TypeExtensions.GetConstructors(type)
                                select new {
                                    ctor = ctor,
                                    parms = ctor.GetParameters()
                                }).Where(<>h__TransparentIdentifier0 => {
                                    if (<>h__TransparentIdentifier0.parms.Length == 1)
                                        return TypeExtensions.IsAssignableFrom(<>h__TransparentIdentifier0.parms[0].ParameterType, dictionaryAdapter.Meta.Type);
                                    return false;
                                })
                                select <>h__TransparentIdentifier0.ctor).FirstOrDefault();
                                if ((object)constructorInfo != null) {
                                    object[] array = new IDictionaryAdapter[1] {
                                        dictionaryAdapter
                                    };
                                    parameters = array;
                                }
                            }
                            if ((object)constructorInfo == null)
                                constructorInfo = TypeExtensions.GetConstructor(type, Type.EmptyTypes);
                            if ((object)constructorInfo != null)
                                storedValue = constructorInfo.Invoke(parameters);
                        }
                    }
                }
                if (storedValue != null) {
                    using (dictionaryAdapter.SuppressNotificationsBlock()) {
                        initializer?.Initialize(dictionaryAdapter, storedValue);
                        property.SetPropertyValue(dictionaryAdapter, property.PropertyName, ref storedValue, dictionaryAdapter.This.Descriptor);
                        return storedValue;
                    }
                }
            }
            return storedValue;
        }
        private static bool IsAcceptedType(Type type)
        {
            if ((object)type != null && (object)type != typeof(string) && !type.GetTypeInfo().get_IsPrimitive())
                return !type.GetTypeInfo().get_IsEnum();
            return false;
        }
        private static Type GetInferredType(IDictionaryAdapter dictionaryAdapter, PropertyDescriptor property, out IValueInitializer initializer)
        {
            Type type = null;
            initializer = null;
            type = property.PropertyType;
            if (!typeof(IEnumerable).IsAssignableFrom(type))
                return type;
            Type type2 = null;
            if (type.GetTypeInfo().get_IsGenericType()) {
                Type genericTypeDefinition = type.GetGenericTypeDefinition();
                Type type3 = TypeExtensions.GetGenericArguments(type)[0];
                if (false || (object)genericTypeDefinition == typeof(List<>)) {
                    if (dictionaryAdapter.CanEdit)
                        type2 = typeof(EditableList<>);
                } else if ((object)genericTypeDefinition == typeof(IList<>) || (object)genericTypeDefinition == typeof(ICollection<>)) {
                    type2 = (dictionaryAdapter.CanEdit ? typeof(EditableList<>) : typeof(List<>));
                }
                if ((object)type2 != null)
                    return type2.MakeGenericType(type3);
            } else if ((object)type == typeof(IList) || (object)type == typeof(ICollection)) {
                if (!dictionaryAdapter.CanEdit)
                    return typeof(List<object>);
                return typeof(EditableList);
            }
            return type;
        }
    }
}