Reputation: 12381
In my app I need to show a form on mouse click. The problem is that the form is in another assembly and because of lazy nature of assembly loading it is likely that the assembly isn't loaded yet when the mouse button is pressed. So what I have is very noticeable pause before the form finally appears.
I was able to come up with a dumb fix by calling new FormFromAnotherAssembly()
in my initialization method. That, of course, took care of things and the pause is no longer there, but it's very ugly. The only thing I like about this solution is that I don't have to mess with paths and assembly names which I have to do if I want to use something like Assembly.Load
.
So, what's the good, robust solution of choice if I want to make sure the assembly is loaded before I actually need it?
Thanks in advance.
Upvotes: 25
Views: 18956
Reputation: 449
I think that the easiest way is to just use the assembly name in Assembly.Load():
System.Reflection.Assembly.Load("ICSharpCode.AvalonEdit");
You can find the assembly name under the reference properties in Visual studio:
This way you can avoid entering dll file paths etc. I use this to speed up the loading of a dialog that uses this DLL. As soon as the program main window is fully loaded it launches a background thread that just calls Assembly.Load(). When the user opens this dialog the small lag of loading this DLL is gone.
Upvotes: 2
Reputation: 64933
I believe that Assembly.Load is the way.
During application startup you should locate modules, plug-ins or any other run-time pluggable and load their assemblies into application's domain (AppDomain).
Or another and better option: Why don't you use inversion of control for that?
You can use Castle Windsor for that. Let's say you've 4 forms to load in run-time, so, you can create 4 components of Form class which their implementation are the 4 forms to load during the life-cycle of your program.
How to pre-load with this approach? You simply resolve all dependencies/components that are of type of Form and you got it:
container.ResolveAll<Form>();
Later you'll get a particular form:
container.Resolve<Form>("CustomersForm"); // Just an example
If you don't know inversion of control, comment out and I'll assist you, no problem! :)
Upvotes: 2
Reputation: 1062502
Explicit pre-load in your init is probably still your best option.
a typeof(SomeTypeFromAnotherAssembly)
should be enough - along with some opaque method that can't be optimised away; perhaps:
GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));
This avoids the new
. Note that this will be loaded, but not JITted etc.
If you wanted, you could do it on a BG thread:
private static void LoadSomeStuff(object state) {
GC.KeepAlive(typeof(SomeTypeFromAnotherAssembly));
}
...
ThreadPool.QueueUserWorkItem(LoadSomeStuff);
Upvotes: 23
Reputation: 101130
var yourAppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Assembly.Load(Path.Combine(yourAppPath, "formAssembly.dll"));
Will that do?
Upvotes: 1