Code Smell – Two Libraries Connecting to the Database

api-designcdatabasenet

In the current company that I work for there is a very large Utilities library. It was written a few years back (long before I joined) and has grown ergonomically over time to now do everything:

  • Sending Emails
  • Exporting Files in different formats, i.e. CSV, tab delimited
  • Receiving data from 3rd party providers, i.e. Bloomberg, Facset
  • Sending files to SFTP sites
  • Generic database connection

The list goes on and it is pretty ugly really.

The original developer here used it in every application that he wrote for convenience sake and added to it as necessary. The utilities library itself has references to 3rd party API’s to do some data receiving from Bloomberg/Factset. Using these 3rd party API’s means that any project that wants to reference the large Utilities library also then needs to have the Bloomberg API’s and Facset API’s with it. The list is starting to grow too and it is becoming very unmaintainable and unnecessary to have all these 3rd party DLL’s accompanied with this large Utilities project but are required to compile it.

I want to rewrite this entire library it to more manageable libraries. i.e:

  • CompanyName.Email
  • CompanyName.FileExporter
  • CompanyName.Bloomberg

Each project will then only reference the necessary projects it needs to get its job done. i.e. reference the CompanyName.Email to send emails.
I have no issues doing that, but the complication facing me is that some of the new libraries will require their own database connection and queries.
The example below is:

[HolidayChecker]
[HolidayChecker.DAL]

We store a list of holiday days in the database. What I would want the HolidayChecker project to do is expose a method (amongst others) to check if a particular date is a holiday.

public interface IHolidayChecker
{
    bool IsHoliday(DateTime dateToCheck);
}
public class HolidayChecker : IHolidayChecker
{
    public bool IsHoliday(DateTime dateToCheck)
    {
        //Query database for date logic...
    }
}

Many applications will then reference this HolidayChecker project and use the IsHoliday method. These applications will also have their own connection and queries to the database to perform their own tasks.

[GenericApplication (References HolidayChecker)]
[GenericApplication.BusinessLogic]
[GenericApplication.DAL]

If the application and the HolidayChecker project both access the database and query the data, this comes across heavily as code smell. Is anyone aware of a tidier way of achieving this? Or is there? Is this something I will just have to live with?

EDIT:

Thinking about this overnight, I don't think it is a bad as first thought. Projects like ELMAH are stand alone that also connect to the database and do their own queries. As @Allan pointed out, it is just a matter of designing my HolidayChecker project correctly.

Best Answer

I would suggest that organization may be more important than separation. Separating things into separate DLLs could be useful when a client library only needs part (but not all) of the total functionality.

My suggestion would be to follow the DRY principle -- don't duplicate code. Shared code can be put into a base library that is shared among the more specialized ones. Just be careful that you don't get yourself into a dependency/DLL hell where you have to mess with an entire dependency tree...

To get around the DLL hell, I would recommend creating a single solution (.sln) file for the whole thing, then break down the separate DLLs as projects within it. That way you can rebuild everything at once, but still have some flexibility.

Another thought: as you work through your code base, you may find that organizing by business use case might not be as effective as by type of functionality or something else.

Related Topic