4

I am currently refactoring some old code and I am facing some architectural problems.
Currently 3 applications are working with the same Database (as follows):

  1. Content inserted by user
  2. Content moderated by a team
  3. Content listed by a website

Each application is using a generated DLL which implements the functionalities but the problem comes when I need to modify something related to the database. Then I have to copy the DLL on each project.

I know that it's seems not to hard to modify just 2 DLL-s but the company has almost 30 instances of this setup and sometimes modifications has to be published live on the fly without breaking anything.

I don't know if it's possible to find a solution where I can make the modifications just in one place (Database functionalities) and not break anything in production.

  • 5
    Have you automated the DLL Copy process across for the 30 instances? – JeffO Mar 17 '16 at 8:18
  • From the question, it is not inherently clear where your main problem is - is it just the deployment of that DLL to 30 places (which is not too hard to solve, see the answers below)? Or is your fear changes to the DLL might break one of the application (which has nothing to do with those 30 places, and is not really answered by any of the current answers)? Moreover, you did forget to tell us if you only make backwards compatible changes to the DB, or not. – Doc Brown Mar 19 '16 at 9:09
3
+50

There are a number of ways to solve this problem. Here I'll try to give a few of these:

  1. Have a centralized version of the DLL (say on your company's intranet) and have all apps check on startup (or on an interval) whether the centralized version differs from the one currently installed for the application. If it is, have the application replace it. (Make sure the DLL file is not in use by your application when it is being replaced and then restart the application. (Make sure the user knows to save their work!)). As per @JimmyJames' comment, the version information should be stored somewhere the application can check it easily, for instance in a database.

  2. Using the power of a network domain environment. Assuming the computers the applications run on are part of the same network domain, you could have a startup script (or other automated mechanism) that automatically copies the latest version of the DLL onto each of the computers.

  3. Introduce a new way to connect to the database. I am not sure what functionality you have introduced in the DLL, but this functionality could be implemented as micro-services or webservices (have a look at Service Oriented Architecture (SOA)). This way any update to these functionalities would not require an update of any DLL as long as the interfaces did not change. If they do, only the affected applications would need to be replaced.

In all cases timing might be an issue: if the updating the DLL is required because of changes that are not backwards compatible (say renaming a column name or table name in the database), you should work out a way to make sure that all applications have the new DLL after the changes to the database have been made before connecting to the updated database.

  • 1
    I like #1 but I would recommend putting the version in a table in the DB. The DLL would check that it's version matches the DB. Timing is probably the hardest part. Setting the DB version ahead of the DB update would allow for a reasonable polling interval. – JimmyJames Mar 17 '16 at 14:11
  • I updated the answer to reflect this. – Miguel van de Laar Mar 17 '16 at 14:21
6

By directly coupling the clients to the database, updates will always be a problem.

With a layer in between, you can call it a microservice or an SOA layer or whatever, you can keep the two separate.

The service that sits in between can forward requests on to the database to begin with (or send requests to both and just return the original answer) and no one will know it is there. Then you can change the database and update the code you own in the service that sits in between and then decide how you want to map that on to what the clients expect.

By adding in a version numbering system you can control what changes you make are backwards compatible and send those straight through and what changes will require changes to the client, not just the accessor DLL.

1

It should be the sign that a move to a n-Tier / SOA approach may be beneficial to this project.

Perhaps some part of the database access may benefit not to be done directly, from a DLL, but from a shared service. Then there would be a single point of modification/update, for the whole system.

1

In short: create your own NuGet package feed

Since you are using the .NET stack for development, you can stand up your own NuGet package feed where you can place a NuGet package that contains the database API. You can release different versions in order to maintain backwards compatibility for integrating projects. Any project that wants access to the database need only fire up the NuGet Package Console in Visual Studio, then install-package YourDatabasePackage to include it.

If you update the public API for the database, then you release a newer version of that package to the server. Anyone not ready to use the new API stays on the old version of the NuGet package. When it comes time to use the new API, just fire up the NuGet package console again in your project and type update-package YourDatabasePackage then compile and fix bugs.

This gives all the integrating applications some buffer time in order to start using the new API, but also gives you a controlled manner to roll out updates.

When adding a new project to a solution in Visual Studio, you can look at the on-line templates for a project template called "NuGet Packager". This gives you a one-click way of creating a NuGet package project that compiles the project, creates the DLL file and creates the NuGet package file when you build the solution. It's a great way to start developing your own NuGet packages quickly.

Screenshot of add new project window in Visual Studio with NuGet packager template selected

1

Architecturally, you describe a system with a data store and three actors, with three use cases. The system should provide the services for the use cases. You seem to have several systems collaborating, not very well.

I would tend to push the API for the database towards the database itself. I would tend to write more stored procedures in SQL, for instance, and less "external" code to provide as much of the interface to the data store at the data store, instead of external to it.

If this were SQL Server, I might consider SQL CLR for behavior that couldn't be easily implemented in the native language. The one single place where the behavior is hosted is inside the data store itself.

Now, there might be a whole bunch of reasons that this isn't the right way to go, but it addresses the problem of having more than one place for assemblies to be deployed.

0

I would recommend you to review the Proxy Design Pattern AND a concept for backward compatibility until big bang changes.

I assume, you are not changing interfaces very often but only implementations. This pattern may help you to reduce the need of DLL distribution for every little change. In this way, proxies will point the real implementation and you would change only the real subject at one place, probably very close to DB.

You could implement the proxy pattern for your DLLs like the DCOM (old but still works) does. Or, you can wrap dll calls by a (web)service (SOA) which consumes your dll.

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.