views:

241

answers:

3

I have couple resource DLLs that I currently load when application starts using following code:

Assembly ass = Assembly.LoadFrom(fi.FullName);
Type t = ass.GetTypes()[0];
string ns = t.Namespace;
BaseFacade bf = Activator.CreateInstance(t) as BaseFacade;

// bf.GoWild()...

When I have that BaseFacade I go wild with function calling to obtain resources from DLLs and all that works fine. However that initial LoadFrom is extremely slow and for 10 DLLs I have it takes over 30 seconds.

So, I was wondering of alternative approaches? Are there any? I was wondering if it is possible to do something like:

[DllImport("myResources1.dll")]
public static extern void GoWild();

[DllImport("myResources2.dll")]
public static extern void GoWild();

?? If it is possible, how would I expose those GoWild functions for resource DLLs? Also, how would I point application to location of DLLs considering they are not always in directory of main DLL (and user has option to move those DLLs around)?

Thanks for any advice on this subject!

+2  A: 

It looks from your first snippet that you are loading .NET libraries through reflection. DllImport is for loading unmanaged libraries, not .NET assemblies.

Without much knowledge of the rest of the application, it's hard to suggest any alternative method to what you are doing already. Could you the first code snippet in a background thread?

Steve Danner
Hmph... so thinking about DLLImport is just - stupid? :( OK, learning new thing every day. As for threading - I tried loading all DLLs in separate threads, but it seems calling Assembly.LoadFrom synchronizes threads by having some kind of lock (in Debug output I could see that DLLs got loaded one-by-one)
kape123
+1  A: 

Is the slowness of LoadFrom due to initialization happening in the DLLs, or is it something in the .NET framework?

This may help: http://dedjo.blogspot.com/2008/01/how-to-load-unmanaged-native-resources.html

Scott Smith
I think it has to do with size of DLLs - they are about 10MBs and it takes around 3 seconds to load one. I guess that's OK time when you take into account fact that I'm doing all this on mobile phone...
kape123
+2  A: 

One thing that might improve perf is to not retrieve all types from the loaded assembly. If they are that big (10 MB) I assume there are a significant number of types in each that Reflection needs to work its way through. In other words, get rid of the ass.GetTypes() call since you apparently only need one single type from the assembly.

BTW, accessing the first element in the returned type array seems risky since Reflection doesn't guarantee the order in which the types are returned.

You could instead define an assembly-level custom attribute that specifies which type, derived from BaseFacade, that should be loaded.

Mattias S
That's actually awesome suggestion - I completely disregarded this fact. However, I just performed testing and since I have 1 type per assembly (all others are Embedded resources) - everything works.I'll look up how to do that whole Assembly_level_custom attribute... sounds interesting.Thanks man!
kape123