Thursday, April 7, 2011

Loading different versions of same .Net assembly

In my previous post I described how to load assemblies from a sub folder. You may run into a scenario when assemblies in root folder are referring a particular version of assembly while assemblies in subfolder are referring to a different version of same assembly. Assume this assembly (Lets call it SomeAssembly.dll) is placed in root folder and version no of this is 1.0, now if assemblies in subfolder need to refer 2.0 version of this assembly. So put 2.0 version of this assembly in the subfolder and instruct assembly resolve mechanism to load the assemlies from subfolders if it failed to load automatically. Below code shows how to do it:


static void Main(string[] args)
{
   AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
   string locFormat = Environment.CurrentDirectory + "\\{0}\\" + args.Name.Split(',')[0] + ".dll";
   foreach (string subPath in AppDomain.CurrentDomain.RelativeSearchPath.Split(';'))
  {
     string filePath = string.Format(locFormat, subPath);
     if (File.Exists(filePath) && AssemblyName.GetAssemblyName(filePath).FullName == args.Name)
     {
        return Assembly.LoadFile(filePath);
     }
   }
 return null; // Failed to load
}

Note that this also applicable when using binding redirect is not a solution and you want different components with in you application to use a different version of a private assembly, you can put each of those different version in to seperate subfolders(as assembly file name is same only one assembly can be put in a single folder). Use above code and add these subfolders into probing path as described here.

1 comment:

  1. Were you able to get rid of the warning "MSB 3247 - Found conflicts between different versions of the same dependent assembly" ?

    ReplyDelete

Type based templating

            <DataTemplate DataType="{x:Type vm:SampleViewModel}">                 <DataTemplate.Resources>       ...