views:

363

answers:

8

Hi All,

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

+1  A: 

This is more of a subjective question but IMO it's a good thing to wrap any application/library specific usage into a service model design that has well thought out interfaces so you can easily use DI and later if you ever need to switch from say EntLib Data Application Block to NHibernate you don't need to re-architect you're whole application.

Chris Marisic
A: 

I think it's better to use a wrapper, personally, simply because these are things you don't want to be running when your unit tests run (assuming you're unit testing also).

Jimmeh
+1  A: 

I generally create a "helper" or "service" class that can be called statically to wrapper common functionality of these libraries.

I don't know that there is a tremendous amount of risk in directly referencing/calling these, since they are definitely mature projects (at least EntLib and Log4Net), but having a wrapper isolates you from the confusion of version change, etc. and gives you more options in the future, at a fairly low cost.

Guy Starbuck
+3  A: 

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.

BennyM
+6  A: 

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.

Stefan Steinegger
I would agree that Log4Net is a very simple API but there is no way to extract all the interfaces from log4net and give it to developers so that they can code using only Interfaces. Without a wrapper it makes it very difficult to upgrade the version of library specifically if there are 100s of application using. is there any other solution?
rauts
@rauts: Not 100% percent sure what you mean. When using log4net, you already using interfaces. When they decide to change it, it will have a reason, they will highly consider compatibility and only break it if it is really really worth it. If you decide to use this new feature or concept that caused the interface to change that much, your wrapper will not support this anyway and adapting your wrapper will cause the same changes. There are **conceptual changes and dependencies** which you can't "code away" by writing wrappers.
Stefan Steinegger
@stefan: if you decide *not* to support new features then you can leave your wrapper unchanged. Or if there is a breaking interface change you *may* be able to handle it in your wrapper to avoid breaking the other 100 applications. Of course, if you want to use new features then your point is 100% accurate that you can't code them away.
Tuzo
@Tuzo: If you decide not to use the new features, you don't upgrade to the new version. If it is possible to map the new interface to the old, it will already be available in the product, unless the people writing it are too stupid. So the chance that you get integration of breaking changes for free is almost zero, the chance that you have more work every time is almost hundred percent. The products I know are caring very well about compatibility, because nobody would use or update it if they wouldn't and this would be suicide.
Stefan Steinegger
+1 for "wrappitis". Googling it brings up a single result - this page :)
ohadsc
+2  A: 

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.

Konamiman
Thanks.Now that is a really good reason to use wrapper.
rauts
I've never really understood this argument because it's possible to mock abstract and concrete classes as well as interfaces. I agree that it's better to mock interfaces.
Jamie Ide
+1  A: 

It sounds like you are thinking of wrapping the logging implementation and then sharing with different teams. Based on that here are some pros and cons.

Advantages of Wrapping

  • Can abstract away interfaces and dependencies from implementation. This provides some measure of protection against breaking changes in the implementation library.
  • Can make standards enforcement easier and align different project's implementations.

Disadvantages of Wrapping

  • Additional development work.
  • Potential additional documentation work (how to use new library).
  • More likely to have bugs in the wrapping code than mature library. (Deploying your bug fixes can be a big headache!)
  • Developers need to learn new library (even if very simple).
  • Can sometimes be difficult to wrap an entire library to avoid leaking implementation interfaces. These types of wrapper classes usually offer no value other than obfuscation. e.g. MyDbCommand class wraps some other DbCommand class.

I've wrapped part of Enterprise Library before and I didn't think it added much value. I think you would be better off:

  • Documenting the best practices and usage
  • Providing a reference implementation
  • Verifying compliance (code reviews etc.)
Tuzo
A: 

Yes if being able to replace the implementation is a requirement now or in a reasonable future.

No otherwise.

Defining the interface that your application will use for all logging/enterprising/... purposes is the core work here. Writing the wrapper is merely a way to make the compiler enforce use of this interface rather than the actual implementation.

peterchen