8

I usually found myself designing my application in the following way:

  1. One DLL containing interfaces for a desired subsystem. For example, Company.Framework.Persistence.dll.
  2. One new DLL per each strategy (or implementations) of the said subsystem. For example:
    • Company.Framework.Persistence.MSSQL.dll
    • Company.Framework.Persistence.MySQL.dll
    • Company.Framework.Persistence.FileSystem.dll

This will result in a very big solution with a lot of projects, but on the other hand, would give the consumer the chance to choose the appropiate DLL for his needs.

If we had a single DLL called Company.Framework.Persistence.dll, the consumer would have to load a lot of strategies that he may never use. Having modularized DLL would solve this problem.

Is this good practice? Is there a disadvantage with this design?

3

I think that the advantages of this approach far, far outweigh any disadvantages.

What you're achieving here is more ore less a perfect "implementation" of the I in SOLID by way of the Stairway pattern - that is to say, your application depends "down" on an interface defined in Company.Framework.Persistence.dll and the individual implementations themselves also depend "up" on this abstraction.

This means your application is highly decoupled from any implementation details (of course you'll typically want to compose the actual runtime graph using an IOC Container of some sort) I have shamelessly linked to an existing picture of this pattern from another answer on the subject on Stack Overflow:

Example of Stairway pattern

In the book Adaptive Code via C# the author talks about this approach and specifically calls it out as something that should always be done because it provides such a high level of decoupling. (example)

Another possible advantage is being able to patch individual implementations without worrying that you might have affected others, although this is a fairly minor one once you have been diligent with your regression tests; also being able to deploy the individual implementations in sub-folders which can also contain the specific versions of any 3rd party dependencies they might need is probably going to help keep things nicely organised.

About the only real disadvantage I can think of with this approach is that is that it's possible in theory to change the interface in Company.Framework.Persistence.dll (along with your application's binaries) and neglect to update the corresponding implementation dlls which will lead to runtime errors for your users.

Having been guilty of doing exactly this in the past, I can say that this is really only something that can happen if you are very careless :)

1

I do it that way too.

Projects/dlls are essentially free and make the code more readable and easier to use.

I have known people use a single large DLL and differentiate with name spaces. But as you say they have to deploy unused code, I don't see any benefits to the practice and many downsides such as

  • change to one implementation requires recompile of others
  • unused code is deployed to live (risk of bugs)
  • test code is deployed live (mocks etc, risk of bugs, misconfiguration)
  • obsoleted code requires refactoring to remove, (say we don't use MySQL anymore)
  • have to test unused code before deploying (we are testing right?)
  • refactoring can cause compilation error in unused component (say we change an interface)

I might cut corners and put the concrete implementation with the interface for small applications if it avoids a project which contains only a single interface. But normally I find the interfaces go with the models. So I would have

  • Company.Framework.Models.dll (includes interface for persistence)
  • Company.Framework.Persistence.MySQL.dll (ref Models, but needs to anyway)
  • Company.Framework.Persistence.Mock.dll (ref Models, but needs to anyway)

or (bad shortcut!)

  • Company.Framework.Models.dll (not including interfaces)
  • Company.Framework.Persistence.MySQL.dll (includes persistence interface, ref models)
  • Company.Framework.Persistence.Mock.dll (ref models and sql, but its not deployed to live)

Obvs, its pretty simple to refactor the interfaces out if the application increases in size/complexity

0

The advantage of strategy two is to minimize dll hell.

Usually Company.Framework.Persistence.MySQL.dll will depend on some dll for interfacing with MySql. If I have no interest in MySql, Why should I download the dll from MySql?

Lets say your framework supported 20 different storage providers. Most users only use one. So all users have to go and get 19 dll's they are never going to use just to compile your framework.

By following strategy two you allow your users to only install the dll's they are going to use and thus minimizing dll hell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.