When deciding how to log messages from an application it can be tempting to use the static logger offered by the various implementations NuGet packages. They are ready to use out of the box so you can get started quickly, but saving the 5 minutes to create a wrapper around the logger and inject it where needed will cost you more work down the line.
Using a static instance of anything is a bad idea for different reasons, depending on your use case.
- They are difficult to mock in a unit test so your logger is always writing logs even when they are not needed.
- Lack of mocking also means you cannot write tests to ensure an error log is written in appropriate situations.
- They cannot be replaced at runtime to allow injection of different loggers. This can be important if you are releasing a library for others to use. I define a standard logger interface and log everything to that, then allow clients to inject their own logger as long as it implements my interface.
- If you use the default static Log implementation provided by the vendor, you are locked into their interface meaning you cannot hide or change the surface area of the logger. Changing loggers becomes a MUCH bigger effort if the syntax of the new logger changes.
So that leaves you with some kind of injection. Personally I prefer having all dependencies in the constructor, even if it becomes verbose, because it’s easy to see all dependencies a particular class has.
If you are trying to avoid a big constructor you can look into Property Injection. This requires an attribute on a property of the class, but still gives you all the advantages of injecting the dependencies. If you put the injected property on a base class it will be available for all children automatically.
BTW, I’m not a fan of the Ambient Context pattern I’ve heard described because it’s basically a single purpose DI container, and you must have a concrete reference to multiple ambient service containers. If the easy access of this pattern appeals to you, look into Service Location which is the same idea but more flexible.
Hi, I’m Brad Irby. Since I began my career in Software Development 30 years ago, nearly every project I’ve worked on has been with existing code, not building from scratch. In working with companies like General Electric, Wells Fargo,and Bank of America, I have learned how to work with large legacy systems, and bring them up to date by injecting current development techniques into existing code. In fact I’ve done it so often, Addison Wesley ask me to write a book about it. Learn More