Пример #1
0
 /// <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);
        }