/// <summary> /// Creates new instance. /// </summary> /// <param name="name">he name of the type.</param> /// <param name="type">The underlaying .NET type.</param> /// <param name="versions">The set of versions.</param> /// <param name="versionProperty">The version property to determine version from an instance.</param> public CompositeType(string name, Type type, IEnumerable <CompositeVersion> versions, CompositeProperty versionProperty) { Ensure.NotNullOrEmpty(name, "name"); Ensure.NotNull(type, "type"); Ensure.NotNull(versions, "versions"); Ensure.NotNull(versionProperty, "versionProperty"); Name = name; Type = type; Versions = versions; VersionProperty = versionProperty; }
private CompositeType BuildType(Type type) { ILog log = logFactory.Scope("BuildType"); string typeName = type.FullName; log.Info("Building type '{0}'.", typeName); CompositeTypeAttribute typeAttribute = type.GetTypeInfo().GetCustomAttribute <CompositeTypeAttribute>(); if (typeAttribute != null) { typeName = typeAttribute.Name; } Dictionary <int, ConstructorInfo> constructors = GetConstructors(type); log.Info("Constructors '{0}'.", constructors.Count); IEnumerable <PropertyDescriptor> properties = GetProperties(type); log.Info("Properties '{0}'.", properties.Count()); List <CompositeVersion> versions = new List <CompositeVersion>(); foreach (KeyValuePair <int, ConstructorInfo> constructor in constructors) { IEnumerable <PropertyDescriptor> versionProperties; // Create version from annotated properties. if (TryFindAnnotatedProperties(properties, constructor.Value.GetParameters().Length, constructor.Key, out versionProperties)) { log.Info("Version '{0}' from annotated properties.", constructor.Key); versions.Add(BuildVersion(constructor.Key, constructor.Value, versionProperties)); continue; } // Create version from property name match. if (TryFindNamedProperties(properties, constructor.Value.GetParameters(), out versionProperties)) { log.Info("Version '{0}' from conventionally properties.", constructor.Key); versions.Add(BuildVersion(constructor.Key, constructor.Value, versionProperties)); continue; } throw new MismatchVersionConstructorException(type, constructor.Key); } CompositeProperty versionProperty = null; PropertyDescriptor versionPropertyDescriptor = properties.FirstOrDefault(p => p.PropertyInfo.GetCustomAttribute <CompositeVersionAttribute>() != null); if (versionPropertyDescriptor == null) { if (versions.Count == 1) { log.Info("Implicit version property."); versionProperty = new CompositeProperty(0, "_Version", typeof(int), model => 1); } else { log.Warning("Found '{0}' versions on the '{1}'.", versions.Count, typeName); throw new MissingVersionPropertyException(type); } } else { Func <object, object> getter = delegateFactory.CreatePropertyGetter(versionPropertyDescriptor.PropertyInfo); // Use setter for version only when setter method is present and is public. Action <object, object> setter = null; if (versionPropertyDescriptor.PropertyInfo.CanWrite && versionPropertyDescriptor.PropertyInfo.SetMethod != null && versionPropertyDescriptor.PropertyInfo.SetMethod.IsPublic) { setter = delegateFactory.CreatePropertySetter(versionPropertyDescriptor.PropertyInfo); } if (setter == null) { versionProperty = new CompositeProperty(0, versionPropertyDescriptor.PropertyInfo.Name, versionPropertyDescriptor.PropertyInfo.PropertyType, getter); } else { versionProperty = new CompositeProperty(0, versionPropertyDescriptor.PropertyInfo.Name, versionPropertyDescriptor.PropertyInfo.PropertyType, getter, setter); } } versions.Sort((v1, v2) => v1.Version.CompareTo(v2.Version)); return(new CompositeType(typeName, type, versions, versionProperty)); }
internal VersionBuilder(ManualCompositeTypeProvider provider, int version, CompositeProperty versionProperty, string typeName = null) { State = new BuilderState(); State.Provider = provider; State.Type = typeof(T); State.TypeName = typeName ?? typeof(T).FullName; State.Version = version; State.VersionProperty = versionProperty; }
internal bool TryAddVersion(Type type, string typeName, CompositeVersion version, CompositeProperty versionProperty) { CompositeType definition; if (TryGet(type, out definition)) { List <CompositeVersion> versions = new List <CompositeVersion>(definition.Versions); versions.Add(version); AddOrReplace(type, typeName, new CompositeType(typeName, type, versions, definition.VersionProperty)); } else { AddOrReplace(type, typeName, new CompositeType(typeName, type, new List <CompositeVersion>() { version }, versionProperty)); } return(true); }