The problem with creating type instances using reflection from a strong assembly

I have an existing .NET 2.0 Win Forms that is deployed to the client. For the sake of this scenario, you can call it "WinApp.exe". WinApp.exe has a direct link to a private assembly called Assembly.dll. Assembly.dll has a direct link to another assembly named "Framework.dll". Framework.dll has a type called "IPlugIn". Framework.dll does not have a strong name, but the build version is 1.0. Assembly.dll has a class that implements IPlugIn from Framework.dll.

I have another .NET 2.0 Win Forms solution called "Framework.exe". This Win Forms project also has a direct link to Framework.dll, which is of type "IPlugIn". Framework.dll does not have a strong name, but the version of this assembly is 2.0. Bit for bit, “IPlugIn” in Framework.dll v2 is identical to “IPlugIn” in Framework.dll v1. The code in Framework.exe uses reflection to load the IPlugIn implementation, which in WinApp:

AssemblyName an = AssemblyName.GetAssemblyName("C:\\Program Files\\WinApp\\Assembly.dll");
Assembly dll = Assembly.Load(an);
object o = Activator.CreateInstance(dll.GetType("WinApp.ClassThatImplementsIPlugIn"));
IPlugIn iPlugIn = o as IPlugIn;

So far so good. This code works! Now here is the unpleasant part. I need to assign a strong name to Framework.dll v2 so that it can be added to the GAC. However, WinApp and its dependent assemblies will not be redistributed - they must continue to use the same versions of assemblies that are currently used. When I give Framework.dll v2 a strong name and recompile and run Framework.exe, when this code is executed, I get "InvalidCastException" in the line:

IPlugIn iPlugIn = o as IPlugIn;

I think I am getting this exception because now that one version of Framework.dll has a strong name, the runtime processes the type "IPlugIn" as if it were a completely different type. I need to know if there is a way to solve this problem. Again, the requirements are:

  • I must be able to host Framework.dll v2 in the GAC (so it must have a strong name).
  • WinApp , ( Framework.dll v1). WinApp.

!

+5
1

, , Framework, Framework..NET , IPlugin . , ( , InvalidCastException, null, ).

A

, - , - , , , Framework. , . , , - :

public class PluginWrapper : IPlugin
{
  object fObj;
  PropertyInfo fNameProperty;
  MethodInfo fGetOtherMethod;

  public PluginWrapper(object o)
  {
    fObj = o;
    fNameProperty = o.GetType().GetInterface("IPlugin").GetProperty("Name");
    fGetOtherMethod = o.GetType().GetInterface("IPlugin").GetMethod("GetOther", new Type[] { typeof(string) });
  }

  public string Name
  {
    get { return (string)fNameProperty.GetValue(fObj, null); }
  }

  public IOther GetOther(string name)
  {
    object result = fGetOtherMethod.Invoke(fObj, new object[] { name });

    if (result == null)
      return null;

    return new OtherWrapper(result);
  }
}

:

IPlugin iPlugIn = new PluginWrapper(o);

B

. , , , "" , .

AssemblyName. , Framework AssemblyResolve:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
Assembly dll = Assembly.Load(File.ReadAllBytes(@"C:\Program Files\WinApp\Assembly.dll"));
object o = Activator.CreateInstance(dll.GetType("WinApp.ClassThatImplementsIPlugIn"));
IPlugin iPlugIn = o as IPlugin;

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
  if (args.Name.ToLower().StartsWith("framework,"))
    return typeof(IPlugin ).Assembly;

  return null;
}

, .NET , . - , .

, bindingredirect app.config. , , .

+4

All Articles