Следующее решение возможно только тогда, когда у вас есть контроль над основной исполняемой сборкой, т.е. оно не подходит для автономных библиотек, предназначенных для распространения
У меня была похожая проблема, и я решил ее, создав атрибут для инициализации 'InitializeOnLoad' с параметром Type. Затем в основной исполняемый файл я добавил тривиальный обработчик AppDomain.AssemblyLoaded, который сканирует вновь загруженную сборку для указанного выше атрибута и вызывает для них System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor ().
[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);
}
Кроме того, если вы боитесь, что сборки могли быть загружены до того, как вы перехватили событие AssemblyLoad, вы можете просто запустить AppDomain.GetAssemblies () и вызвать для них «инициализатор».