Flexible class architecture question

D

d0wsdkn02

I need some architecture help. Our app is similar between clients, but
every client has specific needs that can require us to change anything.
I'll concentrate on one class below, but potentially any number of
methods, fields, additional classes, or anything could need to be
changed for a client.

With two clients, one way to implement this would be:

default/Biz.dll
public class CustomerBase // with default implementation

client1/Biz.dll
public class Customer : CustomerBase // with modifications

client2/Biz.dll
public class Customer : CustomerBase // with modifications

The two client dll's would reference the default dll and we would
instantiate the client's version via a factory.

Various issues come up with this implementation:

1. The client dll's have to include Customer implentations (even if
empty). Lots of repetition between clients. Also, if I add a new
class in CustomerBase I have to modify every client dll.
2. What happens when two clients share the same, but different from the
Base, logic. Here it would be a copy and paste and will exist in two
places. Not good.

There's other issues and I would imagine maintainability would spiral
out of control as new clients are added.

A possible improvement I've thought about (kind of a dynamic class
loading factory):

Have Customer defined in all dll's (no CustomerBase). Configure a
hierarchy of dll's for each client (i.e. look in client1 first, then
look in default). Dynamically make the class at run-time based on the
config. Problem 1 above is solved since if no implementation is there
it will just move to the next dll on the list. Problem 2 could be
solved by adding more levels to the hierarchy. Of course,
implementation and going against OOP could be problematic.

To implement it I was thinking:
- Make the class using reflection and the Builder classes (TypeBuilder,
etc.) based on the contents of the dll's in the config.
- Wrap a dynamic proxy (something like
http://www.castleproject.org/index.php/DynamicProxy) around the methods
in the default implementation and override it's implementation
according to the config when called.
- Similar to above, but use full AOP to implement (AspectSharp, etc.).
- Some kind of partical classes implementation over multiple dll's (not
sure if it's possible, and we might have to use .NET v1.1 anyway).

Anybody have thoughts on how best to design this? In short, we want to
flexibly override, add, and refactor anything from the default
implementation; and be able to deploy any dll independently.

Are there any good sample apps that shine in this regard?

Thanks for any help,
feech
 
N

Nicholas Paldino [.NET/C# MVP]

feech,

See inline:
1. The client dll's have to include Customer implentations (even if
empty). Lots of repetition between clients. Also, if I add a new
class in CustomerBase I have to modify every client dll.

This isn't necessarily true. Why not just have a Customer class as a
base with virtual methods that can be overriden? This way, you can provide
a base implementation, and yet, you can specialize what is needed for each
client's implementation.
2. What happens when two clients share the same, but different from the
Base, logic. Here it would be a copy and paste and will exist in two
places. Not good.

Again, you can bake this into the base class. However, if you mean that
you have logic that is shared between two custom implementations, then I
would implement that logic in another external assembly, and create
instances of those classes in each of the custom implementations.

Honestly, don't even bother with the AOP approach. I can't imagine that
what you are doing is so complex that it warrants such an approach. Using
simple polymorphism will work just fine here.

Hope this helps.
 
D

d0wsdkn02

See inline:
This isn't necessarily true. Why not just have a Customer class as a
base with virtual methods that can be overriden? This way, you can provide
a base implementation, and yet, you can specialize what is needed for each
client's implementation.

Not sure I'm getting this. The client assembly will have to have a
blank implementation even if all the base methods are virtual (i.e.
public class Customer : CustomerBase {} ). So, when I add an Order
class I'll need to modify the client assembly to add the stub even if
it uses the default implementation, right?
Again, you can bake this into the base class. However, if you mean that
you have logic that is shared between two custom implementations, then I
would implement that logic in another external assembly, and create
instances of those classes in each of the custom implementations.

Ok. I like that approach. Cool.
 
N

Nicholas Paldino [.NET/C# MVP]

Ok, I see what you are saying. However, if you are concerned with
copying:

public class Customer : CustomerBase {}

Between different implementations, then I would say you have a bigger
problem on your hands =)

Of course, I don't see why you have to do this at all. Like you stated
in your last email, just have your class factory return an instance of
CustomerBase and use that. You aren't required to make CustomerBase
abstract.

Personally, I prefer the overhead of the declaration so I can just new
up my class, and get a type-specific instance as well, but that's just me.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

See inline:
This isn't necessarily true. Why not just have a Customer class as a
base with virtual methods that can be overriden? This way, you can
provide
a base implementation, and yet, you can specialize what is needed for
each
client's implementation.

Not sure I'm getting this. The client assembly will have to have a
blank implementation even if all the base methods are virtual (i.e.
public class Customer : CustomerBase {} ). So, when I add an Order
class I'll need to modify the client assembly to add the stub even if
it uses the default implementation, right?
Again, you can bake this into the base class. However, if you mean
that
you have logic that is shared between two custom implementations, then I
would implement that logic in another external assembly, and create
instances of those classes in each of the custom implementations.

Ok. I like that approach. Cool.
 
D

d0wsdkn02

Thanks very much for your help.

The client I'm working with has this crazy app with lots of intricate
biz logic and everything is configurable between clients. They hired
us to straighten things out and I just want to make sure we don't end
up where they already were. They started with something like we're
talking about here and have now copy & pasted themselves into
unmaintainability. I think it's more of a training issue with some of
them. We'll get it right one way or another.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top