In my webapplication (C#, .Net 3.5), made up of a core class library (containing the business logic, data layer and a couple of utility classes), a windows service project, a webservice project and the website project, I have a couple of static classes in the core library used by all other projects. These classes (for example the Log class) require some initialization (They have an Initialize method) in order to set them up for usage. As an example, the Initialize method of the Log class has a directory path parameter which tells the Log, where to save the logfiles to. Alternativly I was thinking of loading the ‘settings’ for the Log class from a configuration file in the static constructor. The drawback is, that I need different settings for unit-testing then in production code.
Is there a better way to design this? The drawback of this approach is, that all consumers of the static class will attempt to call Initialize. This is not really a problem because once initialized, the method will return immediately instead of executing the Initialize code again, but the design seems a bit weird to me.
I hope my english is sufficient to explain what I’m after. Do not hesitate to ask if the question is not clear enough.
I would try to avoid static classes for things which will require initialization. Make your Log class a normal class, and perhaps have a separate factory class to create instances or a single instance. You might want to use dependency injection to avoid having any statics, although this could get painful for something like logging which is pretty universal though.
For logging in particular, both log4net and log4j (any reason you’ve rolled your own, btw?) use the idiom of asking some factory class for log instances based on names (commonly based on the name of the type using it). This is often stored in a static variable in each class which needs to perform logging. If the logging objects which are returned can still be affected by initialization of the logging subsystem afterwards, you don’t end up with ordering concerns where the DI container has to initialize the logging framework before the logging clients are initialized etc.
Using separate logging objects instead of a static class improves testability – you can replace the logging object during a test with one which records the logs to ensure that (say) auditing information is captured. One downside of the logging objects being known statically is that this reduces the possibilities of running tests in parallel.
Apologies for the somewhat random musings – I haven’t had my first coffee yet. Hopefully it’s helpful though.