Let us burn all those pesky Util & Common libraries

time to read 7 min | 1343 words

image

This is a post that is riling against things like Rhino Commons, MyCompany.Util, YourCompany.Shared.

The reason for that, and the reason that I am not longer making direct use of Rhino Commons in my new projects is quite simple.

Cohesion:

In computer programming, cohesion is a measure of how strongly-related and focused the various responsibilities of a software module are. Cohesion is an ordinal type of measurementand is usually expressed as "high cohesion" or "low cohesion" when being discussed. Modules with high cohesion tend to be preferable because high cohesion is associated with several desirable traits of software including robustness, reliability, reusability, and understandability whereas low cohesion is associated with undesirable traits such as being difficult to maintain, difficult to test, difficult to reuse, and even difficult to understand.

I am going to rip into Rhino Commons for a while, let us look at how many things it can do:

  1. Create SQL CE databases dynamically
  2. Keep track of the performance of ASP.Net requests
  3. Log to a database in an async manner using bulk insert
  4. Log to a collection of strings
  5. Log to an embedded database – with strict size limits
    1. Same thing for SQLite
    2. Same thing for SqlCE
  6. Keep track of desirable properties of the http request for the log
  7. Add more configuration options to Windsor
  8. Provide a static gateway to the Windsor Container
    1. Plus some util methods
  9. Allow to execute Boo code as part of an msbuild script
  10. Allow the execute a set of SQL scripts as part of an msbuild script
  11. Provide cancelable thread pool
  12. Provide an implementation of a thread safe queue
  13. Provide an implementation of a countdown latch (threading primitive)
  14. Expose a SqlCommandSet that is internal in the BCL so we can use it
  15. Allow to easily record log messages executes in a given piece of code
  16. Allow to get the time a piece of code executed with high degree of accuracy
  17. Allow to bulk delete a lot of rows from the database efficiently
  18. Provide an easy way to read XML based on an XPath
  19. Provide a way to update XML based on an XPath
  20. Provide a configuration DSL for Windsor
  21. Provide local data store that works both in standard code and in ASP.Net scenarios
  22. Provide collection util methods
  23. Provide date time util methods
  24. Provide disposable actions semantics
  25. Provide generic event args class
  26. Allow 32 bit process to access 64 bit registry
  27. Give nice syntax for indexed properties
  28. Give a nice syntax for static reflection
  29. Provide guard methods for validating arguments
  30. Provide guard methods for validating arguments – No, that is not a mistake, there are actually two different and similar implementations of that there
  31. Provide a very simple data access layer based on IDbConnection.
  32. Provide a way to query NHibernate by for a many to one using its id with a nicer syntax
  33. Provide a named expression query for NHibernate (I am not sure what we are doing that for)
  34. Provide unit of work semantics for NHibernate
  35. Provide transaction semantics for auto transaction management using the previously mentioned unit of work
  36. Provide a way to map an interface to an entity and tie it to the Repository implementation
  37. Provide a fairly complex in memory test base class for testing Container and database code
  38. Provide a way to warn you when SELECT N+1 occur in your code via http module
  39. Provide nicer semantics for using MultiCriteria with NHibernate
  40. Provide Future queries support externally to NHibernate
  41. Provide an IsA expression for NHibernate
  42. Provide a way to execute an In statement using XML selection (efficient for _large_ number of queries)
  43. Provide a pretty comprehensive generic Repository implementation, including a static gateway
  44. Provide an easy way to correctly implement caching
  45. Provide a way to easily implement auto transaction management without proxies
  46. Do much the same for Active Record as well as NHibernate

Well, I think that you get the drift by now. Rhino Commons has been the garbage bin for anything that I came up with for a long time.

It is easy to get to that point, but just not paying attention. In fact, we are pretty much doctrined into doing just that, with “reuse, reuse, reuse” bang into our head so often.

The problem with that?

Well, most of this code is only applicable for just one problem, in one context, in one project. Bulk Deleter is a good example, I needed it for one project, 3 years ago, and never since. The repository & unit of work stuff has been used across many projects, but what the hell do they have to do with a configuration dsl? Or with static reflection?

As a matter of fact, that Rhino Commons has two (different) ways to do parameter validation is a pretty good indication of a problem. The mere fact that we tend to have things like Util, Shared or Common is an indication that we are basically throwing unrelated concerns together.  It actually get worse if we have something in the common project that can be used for multiple projects. A good example of that would be the in memory database tests that Rhino Commons provide. I have used it in several projects, but you know what? It is freaking complex.

The post about rolling your own in memory test base class with NHibernate show you how simple it can be. The problem is that as timed went by, we wanted more & more functionality out of the rhino commons implementation, container integration, support for multiple databases, etc. And as we did, we piled more complexity on top of it. To the point where it is easier to roll your own than to use the ready made one. Too many requirements for one piece of code == complexity. And complexity is usually a bad thing.

The other side of the problem is that we are going to end up with a lot of much smaller projects, focused on doing just one thing. For example, a project for extending NHibernate’s querying capabilities, or a project to extend log4net.

Hm, low coupling & high cohesion, I heard that somewhere before…