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