有这样一个Control,它需要获得所有BaseType的继承类。由于BaseType的继承类可能存在于当前程序集或者被当前工程引用的其他程序集,所以需要动态搜索可能存在的所有继承类。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
为完成该功能,我写了下面两个方法,记录下来,为以后使用。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
1,这个方法使用了DesignTime下的ITypeDiscoveryService,可以在DesignTime下使用。不过VS2008以下的ITypeDiscoveryService实现逻辑有Bug,不会搜索baseType所在的程序集,所有需要先搜索baseType所在的程序集。 Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<summary>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  Discovers available derived types that derived from baseType at design time.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</summary>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<param name="host">

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  The <see cref="IDesignerHost"/>.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</param>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<param name="baseType">

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  The base type to match.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</param>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<param name="excludeGlobalTypes">

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  Indicates whether types from all referenced assemblies should be checked.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</param>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<returns>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  A collection of types that derived from baseType.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</returns>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
public static Type[] GetDerivedTypes(IDesignerHost host, Type baseType, bool excludeGlobalTypes)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
{

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            if (host == null)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                throw new ArgumentNullException("host");

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            if (baseType == null)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                throw new ArgumentNullException("baseType");

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            List<Type> derivedTypes = new List<Type>();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
        //

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            // Find derived types from base type's assembly.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            //

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            if (!excludeGlobalTypes || !baseType.Assembly.GlobalAssemblyCache)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                Type[] baseTypes = baseType.Assembly.GetTypes();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                foreach (Type type in baseTypes)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    if ((type.IsPublic || type.IsNestedPublic) && baseType.IsAssignableFrom(type))

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
derivedTypes.Add(type);

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            //

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            // Find derived types by ITypeDiscoveryService.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            //

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            ITypeDiscoveryService service = host.GetService(typeof(ITypeDiscoveryService)) as ITypeDiscoveryService;

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            if (service != null)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                ICollection discoveryTypes = service.GetTypes(baseType, excludeGlobalTypes);

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                foreach (Type type in discoveryTypes)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    if (!derivedTypes.Contains(type))

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
                {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
derivedTypes.Add(type);

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            return derivedTypes.ToArray();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
}

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
2,这个方法会搜索当前Domain中所有程序集,注意,继承类所在的程序集会引用baseType所在的程序集,利用这一点可以做一定程度的性能优化。Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<summary>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  Discovers available derived types that derived from baseType from current domain.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</summary>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<param name="baseType">

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  The base type to match.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</param>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<param name="excludeGlobalTypes">

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  Indicates whether types from all referenced assemblies should be checked.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</param>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///<returns>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///  A collection of types that derived from baseType.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
///</returns>

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
public static Type[] GetDerivedTypes(Type baseType, bool excludeGlobalTypes)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
{

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            if (baseType == null)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                throw new ArgumentNullException("baseType");

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            List<Type> derivedTypes = new List<Type>();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            AssemblyName baseAssemblyName = baseType.Assembly.GetName();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            //

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            // Find derived types from CurrentDomain.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            //

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            foreach (Assembly assembly in assemblys)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                // Important, It can improve performance.

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                bool needSearch = false;

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                if (!excludeGlobalTypes || !assembly.GlobalAssemblyCache)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    if (string.Equals(assembly.FullName, baseAssemblyName.FullName, StringComparison.OrdinalIgnoreCase))

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                        needSearch = true;

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    else

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                        AssemblyName[] referencedAssemblies = assembly.GetReferencedAssemblies();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                        foreach (AssemblyName assemblyName in referencedAssemblies)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                        {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                            if (string.Equals(assemblyName.FullName, baseAssemblyName.FullName, StringComparison.OrdinalIgnoreCase))

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                            {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                                needSearch = true;

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                                break;

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                            }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                        }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                if (needSearch)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    Type[] types = assembly.GetTypes();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    foreach (Type type in types)

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                        if ((type.IsPublic || type.IsNestedPublic) && baseType.IsAssignableFrom(type) && !derivedTypes.Contains(type))

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                        {

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
derivedTypes.Add(type);

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                        }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                    }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

                }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            }

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM

            return derivedTypes.ToArray();

Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
}
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM
Ô ÅÖ6!=èÄÉwww.netcsharp.cn1zDI!”ïM