<PackageReference Include="Castle.Core" Version="3.1.0" />

OnDemandAttribute

Support for on-demand value resolution.
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; 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)type.GetConstructor(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.IsInterface) { if (!property.IsDynamicProperty && storedValue == null) storedValue = dictionaryAdapter.Create(property.PropertyType); } else if (type.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 type.GetConstructors() select new { ctor = ctor, parms = ctor.GetParameters() }).Where(<>h__TransparentIdentifier0 => { if (<>h__TransparentIdentifier0.parms.Length == 1) return <>h__TransparentIdentifier0.parms[0].ParameterType.IsAssignableFrom(dictionaryAdapter.Meta.Type); return false; }) select <>h__TransparentIdentifier0.ctor).FirstOrDefault(); if ((object)constructorInfo != null) parameters = new IDictionaryAdapter[1] { dictionaryAdapter }; } if ((object)constructorInfo == null) constructorInfo = type.GetConstructor(Type.EmptyTypes); if ((object)constructorInfo != null) storedValue = constructorInfo.Invoke(parameters); } } } if (storedValue != null) { using (dictionaryAdapter.SuppressNotificationsBlock()) { if (storedValue is ISupportInitialize) { ((ISupportInitialize)storedValue).BeginInit(); ((ISupportInitialize)storedValue).EndInit(); } 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.IsPrimitive) return !type.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.IsGenericType) { Type genericTypeDefinition = type.GetGenericTypeDefinition(); Type genericArg = type.GetGenericArguments()[0]; bool flag = (object)genericTypeDefinition == typeof(System.ComponentModel.BindingList<>); if (flag || (object)genericTypeDefinition == typeof(List<>)) { if (dictionaryAdapter.CanEdit) type2 = (flag ? typeof(EditableBindingList<>) : typeof(EditableList<>)); if (flag && genericArg.IsInterface) { Func<object> func = () => dictionaryAdapter.Create(genericArg); initializer = (IValueInitializer)Activator.CreateInstance(typeof(BindingListInitializer<>).MakeGenericType(genericArg), null, func, null, null, null); } } else if ((object)genericTypeDefinition == typeof(IList<>) || (object)genericTypeDefinition == typeof(ICollection<>)) { type2 = (dictionaryAdapter.CanEdit ? typeof(EditableList<>) : typeof(List<>)); } if ((object)type2 != null) return type2.MakeGenericType(genericArg); } else if ((object)type == typeof(IList) || (object)type == typeof(ICollection)) { if (!dictionaryAdapter.CanEdit) return typeof(List<object>); return typeof(EditableList); } return type; } } }