Type loader : Type « Reflection « C# / C Sharp






Type loader

        

// this class is documented here:
// http://blog.thekieners.com/2010/09/06/type-gettype-implementation-with-help-of-xamlreader/


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Media;

namespace Nova.Core.Common
{
    /// <summary>
    /// Provides functionality to load any type with its class name, namespace and assembly-name within the Silverlight environment.
    /// </summary>
    /// <remarks>
    /// The Type.GetType method is different in Silverlight than in the standard .NET runtime. In Silverlight we have to provide the 
    /// fully qualified assembly name to get a type in a custom assembly. Only build in controls or types in the same assembly are 
    /// excluded from this rule. Full qualified assembly name means a syntax like the following: 
    /// MyComponent.MyType, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4bec85d7bec6698f.
    /// This class uses the XamlReader capability to resolve type during parsing a xaml-string. While this is a little time consuming
    /// the TypeLoader maintains a cache to get types faster.
    /// </remarks>
    public static class TypeLoader
    {
        // cache for resolved type
        private static readonly Dictionary<string, Type> _cache = new Dictionary<string, Type>();

        /// <summary>
        /// Gets the System.Type with the specified name, name space and assembly name.
        /// </summary>
        /// <param name="className">The class name without namespace.</param>
        /// <param name="nameSpace">The name space</param>
        /// <param name="assemblyName">The name of the assembly containing the type.</param>
        /// <returns>The type matching the provided parameters or null if not found.</returns>
        //[DebuggerStepThrough()]
        public static Type GetType(string className, string nameSpace, string assemblyName)
        {
            // check
            if (StringHelper.IsNullOrWhiteSpace(nameSpace))
                return null;

            string xamlNamespace = string.Format("clr-namespace:{0}", nameSpace);
            // assembly name is optional
            if (!StringHelper.IsNullOrWhiteSpace(assemblyName))
                xamlNamespace += string.Format(";assembly={0}", assemblyName);

            return GetType(className, xamlNamespace);
        }

        /// <summary>
        /// Gets the System.Type with the specified name. 
        /// This method overload can be used for:
        /// 1. core controls such as Button, Grid, ListBox, etc. without specifying the namespace or assembly name.
        /// 2. with the qualified assembly name of the type without version and public key token like this: "MyNamespace.MyType, MyAssembly".
        /// </summary>
        /// <param name="className">Pure class name of Core Controls such as Button, Grid, ListBox, etc.</param>
        /// <returns>The type matching the provided parameters or null if not found.</returns>
        //[DebuggerStepThrough()]
        public static Type GetType(string className)
        {
            if (className != null && className.Contains(","))
            {
                string[] qualifiedNameParts = className.Split(',');

                if (qualifiedNameParts.Length == 2)
                {
                    string[] fullClassNameParts = qualifiedNameParts[0].Split('.');

                    if (fullClassNameParts.Length > 0)
                    {
                        // classname
                        string newClassName = fullClassNameParts.Last().Trim();

                        // namespace
                        string nameSpace = "";
                        for (int i = 0; i < fullClassNameParts.Length - 1; i++)
                        {
                            nameSpace += fullClassNameParts[i] + ".";
                        }
                        nameSpace = nameSpace.TrimEnd('.');

                        string assemblyName = qualifiedNameParts[1].Trim();

                        return GetType(newClassName, nameSpace, assemblyName);
                    }
                }
            }

            return GetType(className, "");
        }

        /// <summary>
        /// Gets the System.Type with the specified name. The xaml namespace specifies the namespace and assembly name in the same syntax as in xaml. 
        /// </summary>
        /// <param name="className">The class name without namespace.</param>
        /// <param name="xamlNamespace">
        /// The xaml namespace. This is the same syntax as used in XAML syntax. 
        /// Example: "clr-namespace:MyComponent.SubNamespace;assembly=MyAssemblyName
        /// </param>
        /// <returns>The type matching the provided parameters or null if not found.</returns>
        //[DebuggerStepThrough()]
        public static Type GetType(string className, string xamlNamespace)
        {
            // check input
            if (StringHelper.IsNullOrWhiteSpace(className))
                return null;

            if (className.Contains("."))
                throw new ArgumentException(
                    "className must not include the namespace. Please provide namespace with separate parameter.");

            // check if type is already in cache
            string key = xamlNamespace + "&" + className;

            if (_cache.ContainsKey(key))
                return _cache[key];


            lock (_cache)
            {
                try
                {
                    // check again because another thread might be faster and has already created the cache-entry
                    if (_cache.ContainsKey(key))
                        return _cache[key];

                    // create xaml with a simply Style element and set the TargetType property with the provided type name
                    string xaml = "<Style xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' ";

                    // set the xaml namesapce if provided
                    if (!StringHelper.IsNullOrWhiteSpace(xamlNamespace))
                    {
                        xaml += string.Format("xmlns:tmp='{0}' TargetType='tmp:{1}' />", xamlNamespace, className);
                    }
                    else
                    {
                        // Core controls such as Button, Grid, ListBox, etc do not need a namespace
                        xaml += string.Format("TargetType='{0}' />", className);
                    }

                    // let the XamlParser load the type via the TargetType property 
                    var style = XamlReader.Load(xaml) as Style;

                    if (style != null)
                    {
                        Type targetType = style.TargetType;
                        AddToCache(key, targetType);
                        return targetType;
                    }
                }
                catch (Exception ex)
                {
                    // Try to load type in executing assembly
                    if (!StringHelper.IsNullOrWhiteSpace(xamlNamespace))
                    {
                        // note: Type.GetType uses needs assembly-qualified name of the type to get. If the type is 
                        //       in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply 
                        //       the type name qualified by its namespace.
                        Type type =
                            Type.GetType(string.Format("{0}.{1}",
                                                       xamlNamespace.Replace("clr-namespace:", "").TrimEnd(';'),
                                                       className));

                        if (type != null)
                        {
                            // add to cache
                            AddToCache(key, type);
                            return type;
                        }
                    }

                    //****** DONT SET VALUE TO NULL, BECAUSE OF CASES WHEN AN ASSEMBLY IS  *****
                    //****** LOADED DYNAMICALLY INTO THE APPLICATION DOMAIN                *****
                    // don't let the exception repeat. Set null as cache value
                    AddToCache(key, null);
                    //**************************************************************************/
                }
            }

            return null;
        }

        private static void AddToCache(string key, Type type)
        {
            _cache.Add(key, type);
            CompositionTarget.Rendering -= CompositionTarget_Rendering;
            CompositionTarget.Rendering += CompositionTarget_Rendering;
        }

        private static void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            CompositionTarget.Rendering -= CompositionTarget_Rendering;
            _cache.Clear();
        }

        #region Nested type: StringHelper

        private static class StringHelper
        {
            // helper because .NET 3.5 does not support IsNullOrWhiteSpace
            public static bool IsNullOrWhiteSpace(string str)
            {
                if (str == null)
                    return true;

                if (str.Trim() == string.Empty)
                    return true;

                return false;
            }
        }

        #endregion
    }
}

   
    
    
    
    
    
    
    
  








Related examples in the same category

1.Call GetType() from StringBuilder
2.Call GetType for int data type
3.IsGeneric and IsGenericTypeDefinition
4.demonstrates both the instance and static GetType methods
5.Generic methods, like nongeneric methods, can be invoked dynamically at run time.
6.Type.GetGenericArguments and MethodInfo.GetGenericArguments:
7.Get Generic Type Definition
8.Query properties of a Type
9.Deeper Reflection:Listing All the Types in an AssemblyDeeper Reflection:Listing All the Types in an Assembly
10.Illustrates runtime type creation
11.The typeName parameter is a combination of the Assembly and Type names
12.Call static method GetType from Type to get the Type instance
13.Use GetCustomAttributes from Type to get custom attributes
14.Use Type.GetType to check the type of an object
15.Get object Type Name, UnderlyingSystemType, IsClass
16.Type.GetConstructors
17.Use Type.IsClass to check if a type is a class
18.Print Types
19.Determining the base classes and interfaces for a class.
20.Create Object from assembly name and class nameCreate Object from assembly name and class name
21.Makes a shallow copy of the object to a different class type (inherits from the original)
22.Makes a shallow copy of the object
23.Get all methods from an object
24.Get Derivation from an object
25.The full name of the Array type
26.Change type
27.Does a given Type have a Default Constructor
28.Is it a Nullable Type
29.Is Value Type Unitialized Value
30.Get Type Unitialized Value
31.Is Object Unitialized Value
32.Is it a SubClass for another class
33.Convert type from initial Value
34.Returns all assemblies and their properties
35.Helper to display the "contents" of the Value Object
36.Get a public field value given its name
37.Deep Comparison two objects if they are alike.
38.Set the specified public field value of an object
39.Determine if a type is cloneable: either a value type or implementing ICloneable.
40.Provides a simple reflection based mapper to perform a Data Mapping between two types of objects
41.Represents type declarations: class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed constructed generic types.
42.Gets the attributes associated with the Type.
43.Gets the type from which the current Type directly inherits.
44.Gets a value indicating whether the current Type object has type parameters that have not been replaced by specific types.
45.Gets the type that declares the current nested type or generic type parameter.
46.Gets a reference to the default binder.
47.Represents the member filter used on attributes.
48.Returns an array of Type objects representing a filtered list of interfaces implemented or inherited by the current Type.
49.Returns a filtered array of MemberInfo objects of the specified member type.
50.Gets the number of dimensions in an Array.
51.Searches for the members defined for the current Type whose DefaultMemberAttribute is set.
52.Type.GetElementType
53.Returns a Type object that represents a generic type definition from which the current generic type can be constructed.Returns a Type object that represents a generic type definition from which the current generic type can be constructed.
54.Searches for the interface with the specified name.Searches for the interface with the specified name.
55.Get types implementing Dictionary
56.Returns all the public properties of the current Type.
57.Type to string
58.Get Full Type String
59.Get class members
60.Reflector
61.Is Type a primitive type
62.Find Method With One Parameter Of Type
63.Determines whether the current type is an implementation of the specified interface.
64.Returns equality with type conversion
65.Groups the utility methods that extracts the meta data of a type.
66.Get Friendly Type Name
67.Recursively gets all generic type params in any given type definition.
68.Type Manager
69.Given an anonymous type
70.Type Normalizer
71.Run static/Instance method
72.Get Subclass