This is more like a good practise question. I want to offer different generic libraries like Logging, caching etc. There are lots of third party libraries like MS enterprise library, log4Net, NCache etc for these.
I wanted to know if its a good practise to use these directly or create wrapper over each service and Use a DI to inject that service in the code.
regards
This is subjective, but also depends on the library.
For instance, log4net or NHibernate have strictly interface based API's. There is no need to wrap them. There are other libraries which will make your classes hard to test if you don't have any interfaces in between. There it might be advisable to write a clean interface.
It is sometimes good advise to let only a small part of the code access API's like for instance NHibernate or a GUI library. (Note: This is not wrapping, this is building abstraction layers.) On the other side, it does not make sense to reduce access to log4net calls, this will be used in the whole application.
log4net is probably a good example where wrapping is just overkill. Some people suffer of "wrappitis", which is an anti-pattern (sometimes referred to as "wrapping wool in cotton") and just produces more work. Log4net has such a simple API and is highly customizable, they made it better then your wrapper most probably will be.
You will find out that wrapping a library will not allow you to just exchange it with another product. Upgrading to newer versions will also not be easier, rather you need to update your wrapper for nothing.
If you want to be able to swap implementations of those concepts, creating a wrapper is the way to go.
For logging there already is something like that available Common.Logging.
Using wrapping interfaces does indeed make unit testing much easier, but what's equally important, it makes it possible to use mocks.
As an example, the PRISM framework for Silverlight and WPF defines an ILoggerFacade
interface with a simple method named Log
. Using this concept, here's how I define a mocked logger (using Moq) in my unit tests:
var loggerMock = new Mock<ILoggerFacade>(MockBehavior.Loose);
loggerMock.Setup(lg => lg.Log(It.IsAny<string>(), It.IsAny<Category>(), It.IsAny<Priority>()))
.Callback((string s, Category c, Priority p) => Debug.Write(string.Format("**** {0}", s)));
Later you can pass loggerMock.Object
to the tested object via constructor or property, or configure a dependency injector that uses it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With