views:

394

answers:

4

I am replacing a VB6 application with a rewritten counterpart in VB.Net.
In the VB6 app there was a 'control' application which presented a form to the user and allowed them to select a 'client' from a drop down list. Selecting a client caused the reading of an ini file which set client-specific parameters, including the program names of several dlls, which were also written in VB6 and registered on the subject machine.

For example, each 'client' had a different letter format, and the letter was written by the selected dll. This made everything late-bound, but there is only one user. Most of all, it made it convenient to continually update individual letters by updating only that dll, and dropping the dll on top of the old one. Thus the (clerical) user had only to be told to save this file to the usual folder. I could have compiled everything together in one exe, making my updates larger and more complex.

In re-doing this in VB.Net, how should I replace this sort of approach?

  1. I could tie everything together in one big project (and compile it to an exe which is the large update I was avoiding). Should I just do that?

  2. If I continue with the approach of having my client-specific (.net) dlls compiled separately, does this make sense in the .Net world? How do I call them? Do they need to be registered as they were before? Pros, cons?

  3. What's the right way to do this and still give me the flexibility I had?

+1  A: 

I'd build a text-based format for you letter templates. This way you don't have to compile something every time a template changes. But if you really want to load dlls like that dynamically, you can do so by using the System.Addin namespace or by using reflection, Activator.CreateInstance(), having the types you care about inside the dll implement a specific interface and marking them with a specific attribute.

Joel Coehoorn
Thanks. The letters are complex, with logos etc. and they were only an example.. other dlls read data files etc. I'll look into the namespace you mentioned and reflection, but I'm thinking maybe it's not really a smart design.
+1, Go data-driven wherever you can.
MarkJ
+1  A: 

There are a few ways that I can think of immedately to give you this sort of functionality.

  1. Use Reflection and load the assembly dynamically at runtime. (This is well documented and not as hard as it looks.)
  2. Use an IoC container such as Unity from the Microsoft Enterprise Library.
  3. Use the MEF framework. (Also from Microsoft)
  4. Use a resource file for each set of templates.

The IoC container could be implemented with different containers for each user with each container wiring up the different assemblies. And I think would suit your requirements better.

I haven't had a chance to look at MEF yet, but I think that that does the same as Unity but using attributes to do the wiring up instead of a config. That may prevent you from dynamically changing the templates.

Using a resource file system would work and is realatively easy to load, but then you wouldn't be able to include code with your templates, which may or maynot be a problem depending on what the VB6 classes are actually doing at the moment.

Of course you could not rewrite the VB6 templates at all and just use COM interop to access them. But then you would still be needing to support VB6 code and probably not what you are after.

David McEwing
Much better than the answer I was just writing.
Dennis Palmer
Thanks. It seems complex to keep this structure in .Net, and its benefit is marginal. I think I'll just incorporate all the modules together and do a complete refresh every time something changes.
A: 

Some good answers, but can I give some advice? Do be sure rewriting is the right move. It's a common pitfall to optimistically start rewriting a large application, make good progress fixing flaws in the old architecture, and then get bogged down reproducing functionality you've taken for granted for years. At this point everything gets very uncomfortable and projects often fail.

The official advice from a Microsoft UK webpage.

Performing a complete rewrite to .NET is far more costly and difficult to do well [than converting VB6 to VB.NET semi-automatically] ... we would only recommend this approach for a small number of situations.

And a quote from a Microsoft employee's blog:

Many companies I worked with in the early days of .NET looked first at rewriting driven in part by a strong desire to improve the underlying architecture and code structures at the same time as they moved to .NET. Unfortunately many of those projects ran into difficulty and several were never completed. The problem they were trying to solve was too large.

Having said that, some people do successfully rewrite VB6 apps in .NET and are very happy with the result. But do think it through first.

MarkJ
Thanks. It actually is not that large an application and there are some important .Net features I want to use. I actually took a shot at it already and I think I'll persist. With a due amount of caution as advised!
A: 

The Global Assembly Cache takes on some of the role that the registry played in COM.

Bob Riemersma
This actually points to more of the idea I had. If I replace modules in the GAC, then any app that uses them is in effect 'updated' just as it would have been in VB6, right? An they don't have to be in the GAC, really, do they? Can't they be in a well-known local folder?