views:

42

answers:

2

Hi,

this is more of a design question:

lets say that I have some internal type definitions that I absolutely want to keep secret (not exposed to my service consumers. However, i do need to exchange data with the service users. some of the types I want to share with the users are exactly the same as the internal ones while others are a simplified version of the internal type. same object or not - my primary concern is that the internal object will never be exposed to the outside world, my secondary concern is now making too much duplicate code...

The Idea is that I really don't want to have the situation where the internal object will be exposed to the WCF by mistake(this has just happened to me for internal object not even marked as [DataContract] ), so I thought about the following approach:

  1. Design My WCF service contracts files not having any reference to the internal types namespace. - this will provide some better safety.

  2. Implement translations between the internal types and its corresponding public representation objects at the service implementation code.

Is this the right approach? are there any known patterns that better solve the above issues?

Many thanks, Ofer

+1  A: 

Make two types. Duplicate code is bad, yes, but having your internal data and your DTO be different and have a translation between them is pretty common.

Personally, I'd argue that it's almost a best practice.

Additionally, consider your contract and whether you need to send the entire data object down or whether you can just issue remote commands on it.

kyoryu
+1  A: 

Firstly I'd like to re-assure you that it is perfectly ok to have a different model within the service implementation compared to the service level model. There several reasons why this can happen and/or is useful, two of which are:

  • You con't want to expose all your implementation but maybe just a subset. This is the scenario that you are describing.
  • You have found a better abstraction for the domain which you want to use for your service implementation but which would be too hard to understand for users of your service.

Both reasons are valid in my experience and both provide value. With my team I often refer to the model used as the service level as "Service Level Domain Model". I'm sure there are other, better names.

Make all types (interfaces, classes, structs, enums) you don't want to expose internal to the assembly implementing them. Then create duplications - these may be DTO (data transfer objects) or others - for the pieces you want to expose but duplicate only the data, not the implementation. Depending on the implementation you may be able to use some reflection-based wizardry to exchange data between internal and external representation. Be aware of the possible performance implications. Copying data comes at a price.

Also, instead of moving the data to the service client and back to the service, you may also be able to identify operations on that data that can be performed by the service. That way you avoid the problem in the first place.

Good luck!

John
You could also use something like AutoMapper (automapper.codeplex.com) to handle much of the boring assignment code between two types...
marc_s
This answer together with AutoMapper solves your architecture problem.
Ladislav Mrnka