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

OnDemandAttribute

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