The best and safe way is to design your library so that the caller will initialize your library when they know they can.
When an assembly is loaded, the CLR employes a lot of machinery to have the job done, starting from how the inner platform is designed to load modules up to the CLR itself. Each involved actor has their own limitations.
Executing code when a module is loaded is not the best practice on Win32 for the same reason: you cannot know what your caller is doing; also, the changes your doing could possibly alter the current AppDomain, but may not plbe propagated in all the other AppDomain of the application.
A conscious initialization method is the cleanest way to let the caller to control the initialization of your assembly.
All the other answers partially address the issue, but could introduce unwanted side effects and non deterministic behaviors.