views:

106

answers:

4

I have a ASP.net application that is referencing a external assembly that I need to dynamically load and discover any types implementing a known interface. The problem I am having is that the type I reflect does not match the same interface that is running and so I cannot cast it.

Example:

This code is run in ASP.net app.

var assembly = Assembly.LoadFile(Path.Combine(HttpRuntime.BinDirectory, "ExternalAssembly.dll"));

var type = assembly.GetExportedTypes().First<Type>(x => x.Name == "AClass"); // AClass implements IAInterface

var reflectedInterface = type.GetInterface(typeof(IAmAInterface).ToString());

if (reflectedInterface != typeof(IAmAInterface))
    throw new Exception("This makes me sad"); // This code gets run

The only difference I can see between the reflected interface I loaded from the bin and the interface returned from typeof is that the typeof assembly has a location in the temp ASP.net path (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\08c43c8b\3adac8cf\assembly\dl3\eb7a4127\0235ea60_a3c8c901\ReflectionTest.DLL)

Thanks Paul Alexander I have changed the code to use the Assembly.Load method not Assembly.LoadFile which solves the problem.

wwilden: I also tried extracting the interface into it's own assembly and this does also solve the problem.

+1  A: 

Where is your interface type defined? Does it exist both in the reflected assembly as well as in the application itself? Then you actually have two different interfaces, even though they have the same namespace and name.

What you need to do is extract the interface from the reflected assembly and put it into another assembly that you refer to both from the reflected assembly as well as your application. Then it should work.

Ronald Wildenberg
+2  A: 

When you use LoadFile the assembly is not loaded into the same context as your other assemblies at runtime so to the CLR interface runtime types are different. You can read more in Suzanne Cook's Debugging Assembly Load Failures.

If the assembly that you're loading is already in the Bin directory - you can load it by name. You don't need to know the exact path as the Bin folder is already in the assembly probing path.

Paul Alexander
A: 

Apart from your problem, if you have a lot of assemblies to dynamically load, remember that they will remain in memory until the ASP.NET worker process reloads. This could influence your server's performance.

You could load the assemblies in a separate AppDomain (the smallest unit that is possible to unload), load a proxy class in that AppDomain which you reference with .NET remoting. Once finished, you unload the AppDomain.

bgever
A: 

There is an interesting article over at CodeProject about a situation like this. Where you have a class that has a structure that is identical with an interface without implementing the interface itself. The article outlines a method of dynamically creating wrapper classes that implement the needed interface. It could be helpful in your situation.

Rune Grimstad