views:

166

answers:

4

We have a piece of functionality that is used by several different applications (clients) on the same server. It can best be modeled as a service, has a backend database, and there will only be one version of the functionality and the database in use at any one time.

Until now we have employed simple DLL-reuse, with the functionality, its configuration file, and dependencies deployed everywhere it is used. Because any changes now have to be made several places, this method is painful when creating new versions of the functionality or when new clients want to use it.

We are wondering if there is a better way to do this, and have come up with two possible alternatives.

  1. Put the DLL (and the dependencies) in the GAC. The question is then how to configure the component. As the clients have no interest in the configuration, we are leaning towards storing the config file in a hard-coded path on the server.

  2. Publish the functionality as an internal (REST-based) service. Access to it can be limited to internal clients using the firewall.

As we see it, the pros of #1 seem to be performance and possibly security, whereas #2 can be seen as simpler to set up.

Are we missing anything important here? Has anybody been in a similar situation before and wants to share some insight?

+1  A: 

This is a problem I've struggled with many times and there really isn't any best answer other then it depends. My personal opinion is that you need to stay away from option 1 for a couple of reasons:

  1. By having all your clients share a single binary it will now require all of your clients to be tested each time you make a change to it. Now I know in your exact case you might have to do this anyways since we can assume you would be modifying the database that sits behind the component.
  2. Do not hard code anything. You can store your configuration path in an AppSettings section in the machine.config file.

As for option 2 one alternative would be to use WCF (assuming your environment can support it). Using WCF you could then use a TCP transport using binary serilization (And there might be a shared memory transport). Both of these would help bring the performance gap closer (Although option 1 will always outperform a service based approach).

By going with option 2 you also alleviate the need to retest all clients, as you can develop automated tests to validate that your contract is not broken. This will allow you to publish to a single place, run quick automated tests, and know that your not breaking the clients.

With that said you can accomplish the same thing using option 1 and a good set of unit tests, but based on my experience option 2 will be easier in the long run.

Option 2 also lets you scale out the service in the future if you ever need more CPU power.

Personally I think Option 1 is easier to setup, as you won't have to deal with configuring your firewall, handling authentication, setting up a service etc...It will also be easier to debug (distributing an application introduces new types of failures for example the site hosting your service crashes and your clients start getting failures).

One last suggestion is that you use a proxy / facade pattern to insolate your clients from the actual location of the service. This will let you expand over time without having to modify the client code.

JoshBerke
A: 

I'd say that using Option 1 would be simpler and easier, especially as youwill just have to spend extra time limiting the availability of the REST. (pun intended!)

Lucas Jones
A: 

Josh points out WCF as an option, and that is surely the way I would go with this.

This problem is exactly what SOA is supposed to solve!

TheSoftwareJedi
A: 

As Josh already said, unfortunately the answer for these kinds of questions is often "it depends".

I'm a big fan of the GAC, but you should only put code there of which you're sure it works (almost) perfectly, and doesn't need to be updated very often. As long as a piece of code is "in development", just publish it together with every application that uses it.