views:

166

answers:

4

I'm writing a static class for logging to be used across my developed solution. There are several components that will use it such as a console application, ASP.NET application, etc...

For the logging to work, it needs to do some initial startup configuration before it can be used, and also some clean up when each application has finished.

Is there a way to do this in .NET without having to expicitly call a StartLog() and FinishLog() method from each application in the solution? Or perhaps a different way of looking at this entirely?

I've been thinking about using locks in each Log() method to check whether the logging class has been initialised, however the potential overhead both in performance and complexity scares me.

+3  A: 

You can use a type initializer (e.g. a static constructor) for the startup side of things - that will automatically be called when you first use the class.

Detecting shutdown is harder... there's AppDomain.ProcessExit and AppDomain.DomainUnload which might be enough for you... just subscribe to the events and react accordingly.

Jon Skeet
This still requires him to call StartLog() (i.e. first use his class). I don't think there is a way around that, just figured it might be good to make that more explicit.
Erich Mirabal
I'm considering a static constructor and what appears to be its equivalent destructor: AppDomain.DomainUnload. However MSDN states the DomainUnload event is never raised in the default app domain so this doesn't appear to be an option.
Alex Angas
That's why I suggested you look at ProcessExit as well :)
Jon Skeet
+2  A: 

Read up on singletons, Jon Skeet has a great article. Using this you can ensure the type is constructed only once. Have a look at the end when he talks about the performance of the locks. Just some food for thought.

JoshBerke
A: 

A singleton pattern whereby you are not re-instantiating the Log class each time but using a getInstance() method would work

Dean
+1  A: 

Singleton pattern would probably work best for you. The static _instance variable is initialized in the start so its Log() constructor is called and you can do the initialization here. As it implements IDisposable and overrides Finalize it will have Dispose() method which would be called when the application exits and the static instance variable is disposed.

public class Log : IDisposable {
  private Log() {
    // Initialize logic
  }

  public LogMessage(string wah) {
    // Write
  }

  public void Dispose() {
    // Clean up
  }

  public override void Finalize() {
    Dispose();
  }

  private static Log _instance = new Log();
  public static Log Instance { get { return _instance; } }

  // You can also implement helper methods on static level if you want to keep the usage same.
  public static Message(string wah) {
    _instance.LogMessage(wah);
  }
}
Mikko Rantanen
You seem to imply that Dispose is called automatically when the process exits. This is not the case.
Wim Coenen
Oh. You got me there. Mixed it with Finalize.
Mikko Rantanen