tags:

views:

391

answers:

3

hi,

i've stuck at a little design problem.

following situation

Library Interface

Contains interface for every model class (getters and setters only)

Libray Businnes Logic

Contains implementations of interface library and DAL. Uses interface & transporter library

Library Transporter: Contains classes for messaging 3rd party web services. Also there i want to add the references or web references of 3rd party libraries if needed. Uses interface library.

So far soo good. There is no circular dependency now. As soon as a webservice needs to be called the business logic library uses the "transporter" library to call the extern method. This works pretty well.

But now i need to create a webservice where 3rd parties should be able to create business objects at our side. I want to create a "Transform library" where bussines objects are transformed to message objects for the the external webservies and vice versa. And there I think is the problem with my current architecture. If i want to create this library, I get a circular dependency. The reasons are

  • Transporter references Transform
  • Transform Library references BL
  • BL references Transporter

I hope that I could explain my situation well.

Thanks for every idea to solve this.

+1  A: 

You may way to rethink your design. Does it make sense to group ALL of your third party web services into one DLL, then move what might considered essential functionality (the transformations) into another library? I think it would make more sense to create individual assemblies for each web service (or group of services, if it makes sense to group them) that has the appropriate functionality in them.

You also have some faulty logic in assuming that "transporter functionality is not need[ed] in every project". If this is the case, why does the Business Logic assembly depend on it?

Adam Robinson
hmm thats a good idea not to create single libraries for every 3rd party web service.your secound point is true, my assumption was wrong. the transport functionality is needed in every project *but not used*. it is used in just special cases. i will correct my question.
nWorx
A: 

I would put the transformation code in the transporter library. The transformations are service-specific and there isn't any need to separate them from the transports. You might want to use namespaces to separate different services and their transformations. I would also consider not putting all the services into a single library. You lose the ability to reference them in a granular fashion if you put them in a single library -- it's all or none.

tvanfosson
i tried this, but i would need a reference from transport -> bl and bl -> transport, and again a circular dependency i don't know how to create valid business objects in transform (namespace or library)
nWorx
+8  A: 

Dependency injection to the rescue:

  1. Create a ITransporter interface which models the service provided by "Transporter". Put it in the interfaces library. Make Transporter implement ITransporter.
  2. In your business library, program against the ITransporter interface instead of directly using Transporter. Now the business library doesn't need a dependency on the transporter library anymore.
  3. In your application/web service where you glue everything together, create an instance of Transporter and inject it where you need an ITransporter object in your business code.
Wim Coenen
+1 for the right sledgehammer. There still might be a less forceful solution, though, as by rethinking the modulization.
Steven Sudit
hmm sounds goodso i also should include the transformations in the transporter library?
nWorx
@unicron: not necessarily.
Wim Coenen