I know this question is similar to several previous ones, but I can't find an exact answer. I have an application framework that, amongst other things, handles unhandled errors. At the moment I require that the host application calls a Register
method in the application's Main
method to register the handlers and various sub-systems. I'd really like to get rid of this dependency and replace the Register
method's parameters with some assembly-level attributes. So, what I need is a way of detecting that the host application has star开发者_JS百科ted from within my assembly - as if it were part of the .NET framework.
I'd like to avoid any explicit calls from within the host app, or any special lines in the configuration file (although these are more acceptable). So just adding a reference to the assembly causes the features to be initialised when the application starts. Has anyone worked out a way of making this happen?
To make things clear, here is an example of my ideal before and after scenarios:
// BEFORE:
[System.STAThread]
private static int Main(string[] args)
{
SupportLibrary.Register(typeof(Program).Assembly, SupportLibrary.ApplicationType.WinForms);
// Get the application initialised...
}
// AFTER:
[System.STAThread]
[SupportLibrary.ApplicationType(SupportLibrary.ApplicationType.WinForms)]
private static int Main(string[] args)
{
// Get the application initialised...
}
The point being that I would like to get rid of the explicit call to register the support libraries and instead have them implicit registered when the application starts and the support assembly loads.
So, I've found the answer. This may not be applicable in every case, but it works for me because the way in which my library is used means that it is always loaded when the application starts. The CLR specification provides for Module Initializers to be defined. These are called the first time a module (e.g. an assembly) is accessed and before any code is executed - which is exactly what I want. There is no direct provision for specifying these in C#, but this article:
http://tech.einaregilsson.com/2009/12/16/module-initializers-in-csharp
provides the tools necessary for injecting the IL directly into your assembly after compiling (which works for me because I am not signing or obsfuscating my code). I hope that helps someone.
The easiest way to do this is a way with config file - just add custom section where you will write all assemblies needed to be initialized. Than your host app will go throught that list and call Assembly.Load()
method on each of the assemblies you need. After that you can perform any necessary initialization (marking methods to be called in the assemblies with custom attributes, etc).
I'm not sure if there is a way (I think it is) to load all application's assemblies at once. If you can find such way than you can mark all assemblies needed to be initialized with suctom attribute and then just go through all loaded assemblies loaded (AppDomain.CurrentDomain.GetAssemblies()
) to filter ones with your attribute.
精彩评论