I have a .net library dll that acts like a functional library. There are a bunch of static types along with static methods.
There is some initialization code that I need to run to set up the library ready for use.
When the assembly gets loaded is there a way to ensure that a particular method is run? Something like AppDomain.AssemblyLoad but called automatically from the assembly itself. I was thinking that maybe there is something like an AssemblyAttribute that could be used?
At the moment I have this initialization code in a static constructor but as this is a library with many entry points there is no guarantee that this particular type will be used.
Thanks!
If an assembly is loaded into the same AppDomain, then the class can be instantiated in the usual way. But if an assembly is loaded into a different AppDomain then it can be instantiated using reflection. Another way is an interface.
In summary if you get the "Could not load file or assembly error", this means that either your projects or their references were built with a reference to a specific version of an assembly which is missing from your bin directory or GAC.
LoadFrom(String) Loads an assembly given its file name or path.
Yes there is - sort of.
Use the excellent little utility by by Einar Egilsson, InjectModuleInitializer.
Run this executable as a post build step to create a small .cctor function (the module initializer function) that calls a static void function of yours that takes no parameters. It would be nice if compiler gave us the ability to create .cctor(), luckily we rarely need this capability.
This is not a complete DllMain replacement, however. The CLR only calls this .cctor function prior to any methods called in your assembly, not upon assembly load. So, if you need something to happen upon assembly load, you need to have the loading code call a method directly or use the hack I detailed https://stackoverflow.com/a/9745422/240845
The following solution is possible only when you have control over the main executing assembly, i.e. it's not suitable for standalone libraries meant for distribution
I've had a similar problem and solved it by creating an assembly-targeted attribute 'InitializeOnLoad' with a Type parameter. Then, in the main executable, I've added a trivial AppDomain.AssemblyLoaded handler, which scans the newly loaded assembly for the aforementioned attribute and calls System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor() on them.
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public class InitializeOnLoadAttribute : Attribute { Type type; public InitializeOnLoadAttribute(Type type) { this.type = type; } public Type Type { get { return type; } } } // somewhere very early in main exe initialization AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(AssemblyInitializer); static void AssemblyInitializer(object sender, AssemblyLoadEventArgs args) { // force static constructors in types specified by InitializeOnLoad foreach (InitializeOnLoadAttribute attr in args.LoadedAssembly.GetCustomAttributes(typeof(InitializeOnLoadAttribute), false)) System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(attr.Type.TypeHandle); }
additionaly, if you are afraid that assemblies might have been loade before you hook the AssemblyLoad event, you can simply run through AppDomain.GetAssemblies() and call the 'initializer' for them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With