예제 #1
0
        /// <summary>
        /// Dynamically generate a composite class which inherits from a base type and includes all the properties and
        /// applicable interfaces from a list of types which inherit from the base type
        /// </summary>
        /// <param name="baseType">The base type</param>
        /// <param name="derivedTypes">List of types inheriting from the base type</param>
        /// <returns>Dynamically created composite of the given types</returns>
        public Type GetCompositeClass(Type baseType, List <Type> derivedTypes)
        {
            if (baseType.IsSealed || baseType.GetCustomAttribute <NonCompositeAttribute>() != null || derivedTypes.Count == 0)
            {
                return(baseType);
            }

            var dpComparer   = new StringSelectorComparer <DynamicProperty>(dp => dp.Name, false);
            var typeComparer = new StringSelectorComparer <Type>(t => t.FullName, false);
            //List<Type> derivedTypes = ReflectionX.GetAllDerivedTypes(baseType).ToList();

            var dynamicProperties =
                derivedTypes
                .SelectMany(t => t
                            .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
                            .Where(p => p.GetCustomAttribute <NotMappedAttribute>() == null && p.GetCustomAttribute <NonCompositeAttribute>() == null)
                            .Select(p => new DynamicProperty(p.Name, p.PropertyType)))
                .Distinct(dpComparer)
                .ToArray();
            var allProperties = dynamicProperties.Concat(
                baseType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
                .Where(p => p.GetCustomAttribute <NotMappedAttribute>() == null && p.GetCustomAttribute <NonCompositeAttribute>() == null)
                .Select(p => new DynamicProperty(p.Name, p.PropertyType)))
                                .ToList();
            var interfaces =
                derivedTypes
                .SelectMany(t => t.GetInterfaces())   // We only want method-free interfaces
                .Distinct(typeComparer)
                .Where(i => i.GetMethods().All(mi => mi.IsSpecialName) && i.GetProperties().All(p => allProperties.Any(dp => dp.Name == p.Name)))
                .ToArray();
            Type composite = GetCompositeClass(baseType, dynamicProperties, interfaces);

            return(composite);
        }
예제 #2
0
        /// <summary>
        /// Dynamically generate a composite class which inherits from a base type and includes all the properties from a
        /// list of interfaces, and which implements those interfaces
        /// </summary>
        /// <param name="baseType">The base type</param>
        /// <param name="interfaces">List of interfaces</param>
        /// <returns>Dynamically created composite of the base type and interfaces</returns>
        public Type GetCompositeClassByInterfaces(Dictionary <Type, TypeBuilder> typeBuilders, Type baseType, List <Type> interfaces)
        {
            if (baseType.IsSealed() || baseType.GetCustomAttribute <NonCompositeAttribute>() != null || interfaces.Count == 0)
            {
                return(baseType);
            }

            var dpComparer = new StringSelectorComparer <DynamicProperty>(dp => dp.Name, false);

            var dynamicProperties =
                interfaces
                .Recurse(i => i.GetInterfaces()) // GetProperties only return properties on top level interface type
                .SelectMany(t => t
                            .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
                            .Where(p => p.GetCustomAttribute <NotMappedAttribute>() == null && p.GetCustomAttribute <NonCompositeAttribute>() == null)
                            .Select(p => new DynamicProperty(p.Name, p.PropertyType)))
                .Distinct(dpComparer)
                .ToArray();
            var allProperties = dynamicProperties.Concat(
                baseType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
                .Where(p => p.GetCustomAttribute <NotMappedAttribute>() == null && p.GetCustomAttribute <NonCompositeAttribute>() == null)
                .Select(p => new DynamicProperty(p.Name, p.PropertyType)))
                                .ToList();
            Type composite = GetCompositeClass(typeBuilders, baseType, dynamicProperties, interfaces.ToArray());

            return(composite);
        }