Click here to Skip to main content
Click here to Skip to main content
Go to top

Loading .NET types while ignoring version numbers

, 16 Oct 2009
Rate this:
Please Sign up or sign in to vote.
This article shows how to use AssemblyResolve to customize Type loading.

Introduction

Type.GetType("typeName, assemblyName, version, culture") is a common way to load a type object. Unfortunately, the version of the assembly is frequently newer than the one given by the string. Your code might have saved the type name using the Type.AssemblyQualifiedName property, which includes all assembly information, and later tried to load that type, even though the version might have changed. This article will demonstrate an easy way to load a type while ignoring the specific assembly version.

Code

During the normal Type.GetType() call, the AppDomain object will raise an AssemblyResolve event for any assembly it cannot find. (The type string may contain more than one subtype -- Generics.) An optional event handler may load and return an alternative assembly, or null if no assembly is available.

The OnAssemblyResolve handler receives the unresolved assembly name, uses the AssemblyName object to parse it, and attempts to load an assembly with just the name, without any other information.

AssemblyResolve is global for the domain, so we must make sure that other threads, that might potentially try to resolve a type at the same time, do not unintentionally use the same functionality. A boolean field _isGetTypeRunningOnThisThread marked with the [ThreadStatic] attribute cleanly solves this problem.

/// <summary>
/// Load type using <see cref="Type.GetType(string)"/>, and if fails, 
/// attempt to load same type from an assembly by assembly name, 
/// without specifying assembly version or any other part of the signature
/// </summary>
/// <param name="typeName">
/// The assembly-qualified name of the type to get.
/// See System.Type.AssemblyQualifiedName.
/// 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.
/// </param>
public static Type GetTypeFromAnyAssemblyVersion(string typeName)
{
    // If we were unable to resolve type object
    //    - possibly because of the version change
    // Try to load using just the assembly name,
    // without any version/culture/public key info
    ResolveEventHandler assemblyResolve = OnAssemblyResolve;

    try
    {
        // Attach our custom assembly name resolver,
        // attempt to resolve again, and detach it
        AppDomain.CurrentDomain.AssemblyResolve += assemblyResolve;
        _isGetTypeRunningOnThisThread = true;
        return Type.GetType(typeName);
    }
    finally
    {
        _isGetTypeRunningOnThisThread = false;
        AppDomain.CurrentDomain.AssemblyResolve -= assemblyResolve;
    }
}

[ThreadStatic] private static bool _isGetTypeRunningOnThisThread;

private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
    Assembly assembly = null;

    // Only process events from the thread that started it, not any other thread
    if (_isGetTypeRunningOnThisThread)
    {
        // Extract assembly name, and checking it's the same as args.Name
        // to prevent an infinite loop
        var an = new AssemblyName(args.Name);
        if (an.Name != args.Name)
            assembly = ((AppDomain) sender).Load(an.Name);
    }

    return assembly;
}

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Yuri Astrakhan
Architect
United States United States
Yuri works in a small hedge fund in New York, designing various aspects of the trading platform. In the spare time, Yuri participates in various open source initiatives, such as Wikipedia, where he designed and implemented MediaWiki API - http://www.mediawiki.org/wiki/API
 
Yuri writes from New York

Comments and Discussions

 
GeneralEvent subscribtion and multithreading PinmemberAndrew Bibitchev12-Jan-10 1:50 
QuestionWhat's the point? Pinmemberdojohansen17-Oct-09 22:07 
GeneralMy vote of 3 [modified] Pinmemberdojohansen17-Oct-09 21:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140905.1 | Last Updated 16 Oct 2009
Article Copyright 2009 by Yuri Astrakhan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid