• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

WCF serialization architecture question, not creating multiple instances of existing business object

S

sonic

#1
Hello,
I've read a book on WCF and have 3 years of experience using web
services in 1.1 & 2.0 .net frameworks. WCF makes perfect sense and I
am eager to adopt it here, however there is one arhitectual question i
am not clear on. In fact i cant find a clear answer for this anywhere.

One of the pillars of SOA dictates that schema should be shared, and
not the class, but this is hard to implement in an environment where
WCF is used to communicate between web and middle tier of the same
group. Meaning using WCF as transport mechanism between local tiers
where the same business objects are widely used.

If i have a common Trade object within my application framework, I use
it everywhere, on all tiers with and without web services. So the
problem here is, that if each webservice creates a proxy with its own
version of Trade, there will now be multiple instances of Trade
defined each in different namespace:

MyCo.BusinessObjects.Trade
MyCo.Services.TradeManagement.Trade
MyCo.Services.TradeLookup.Trade
etc...

of course if a Trade is looked up using TradeLookup service, and than
attempted to be passed into TradeManagement service it will cause a
problem since they are different objects as far as the framework can
tell.
NOT TO MENTION if one property on Trade changes, all of those service
proxies have to be regenerated now.

so what i've been doing, is generating regular ws proxy, and than
going in and removing all business objects from its definition, and
adding a namespace where they are located so that all services would
be usnig the MyCo.BusinessObjects.Trade.
There is also a library from Think Tekture that will allow you to
generate the proxy dynamically, and use whatever objects you choose
with it omitting their serialization.

To summarize i do not wish to maintain multiple instances of the same
class. My question is, what are some ways to address this using WCF.
 

My Computer

W

William Stacey [C# MVP]

#2
I have also read and thought about these issues lately. My current thinking
is that once your sold on soa (and wcf), you need to throw the shared
assembly stuff out the window and come to grips with the fact that we need
to cut/paste or gen client side classes even if they are exactly the same.
The whole point is not to share clr types (e.g. Remoting), but *only
contract. So we are free of implementation and binary details. If not, we
always end up down a bad path. Your client is a client...does not matter if
it is local or remote, hosted in IIS or self hosted. If we do it right, we
can move that same client code assembly and leverage it all over the
place(remote, console app, win app, service, etc). So there is a small tax
upfront, but it pays dividends the whole life of app. I think we need to
wear two hats during development. When your writing the client, you need to
forget you wrote the service (which is not easy). Pretend someone else
wrote it and just gave you the Mex link. In that case, you will be writing
client totally loose-coupled using just the contracts and interfaces and end
up on the good path. That is my current thinking anyway. Besides, I find
it rare that you can actually use the same type on both sides as
implementations have different goals. The pure data transfer objects (DTO)
that have zero implementation are no big deal to cut/paste anyway and your
still free to extend them at either end or both as long the contract stays.
So you get a lot more flex in many ways then being tied to a clr type.

--
William Stacey [C# MVP]


"sonic" <sonicsoul@gmail.com> wrote in message
news:1176222776.385035.25720@p77g2000hsh.googlegroups.com...
| Hello,
| I've read a book on WCF and have 3 years of experience using web
| services in 1.1 & 2.0 .net frameworks. WCF makes perfect sense and I
| am eager to adopt it here, however there is one arhitectual question i
| am not clear on. In fact i cant find a clear answer for this anywhere.
|
| One of the pillars of SOA dictates that schema should be shared, and
| not the class, but this is hard to implement in an environment where
| WCF is used to communicate between web and middle tier of the same
| group. Meaning using WCF as transport mechanism between local tiers
| where the same business objects are widely used.
|
| If i have a common Trade object within my application framework, I use
| it everywhere, on all tiers with and without web services. So the
| problem here is, that if each webservice creates a proxy with its own
| version of Trade, there will now be multiple instances of Trade
| defined each in different namespace:
|
| MyCo.BusinessObjects.Trade
| MyCo.Services.TradeManagement.Trade
| MyCo.Services.TradeLookup.Trade
| etc...
|
| of course if a Trade is looked up using TradeLookup service, and than
| attempted to be passed into TradeManagement service it will cause a
| problem since they are different objects as far as the framework can
| tell.
| NOT TO MENTION if one property on Trade changes, all of those service
| proxies have to be regenerated now.
|
| so what i've been doing, is generating regular ws proxy, and than
| going in and removing all business objects from its definition, and
| adding a namespace where they are located so that all services would
| be usnig the MyCo.BusinessObjects.Trade.
| There is also a library from Think Tekture that will allow you to
| generate the proxy dynamically, and use whatever objects you choose
| with it omitting their serialization.
|
| To summarize i do not wish to maintain multiple instances of the same
| class. My question is, what are some ways to address this using WCF.
|
 

My Computer

A

Arkady Frenkel

#3
That not only your opinion , William , but third tenet of WCF
Arkady

"William Stacey [C# MVP]" <william.stacey@gmail.com> wrote in message
news:exiy3uLfHHA.2332@TK2MSFTNGP04.phx.gbl...
>I have also read and thought about these issues lately. My current
>thinking
> is that once your sold on soa (and wcf), you need to throw the shared
> assembly stuff out the window and come to grips with the fact that we need
> to cut/paste or gen client side classes even if they are exactly the same.
> The whole point is not to share clr types (e.g. Remoting), but *only
> contract. So we are free of implementation and binary details. If not, we
> always end up down a bad path. Your client is a client...does not matter
> if
> it is local or remote, hosted in IIS or self hosted. If we do it right,
> we
> can move that same client code assembly and leverage it all over the
> place(remote, console app, win app, service, etc). So there is a small
> tax
> upfront, but it pays dividends the whole life of app. I think we need to
> wear two hats during development. When your writing the client, you need
> to
> forget you wrote the service (which is not easy). Pretend someone else
> wrote it and just gave you the Mex link. In that case, you will be
> writing
> client totally loose-coupled using just the contracts and interfaces and
> end
> up on the good path. That is my current thinking anyway. Besides, I find
> it rare that you can actually use the same type on both sides as
> implementations have different goals. The pure data transfer objects
> (DTO)
> that have zero implementation are no big deal to cut/paste anyway and your
> still free to extend them at either end or both as long the contract
> stays.
> So you get a lot more flex in many ways then being tied to a clr type.
>
> --
> William Stacey [C# MVP]
>
>
> "sonic" <sonicsoul@gmail.com> wrote in message
> news:1176222776.385035.25720@p77g2000hsh.googlegroups.com...
> | Hello,
> | I've read a book on WCF and have 3 years of experience using web
> | services in 1.1 & 2.0 .net frameworks. WCF makes perfect sense and I
> | am eager to adopt it here, however there is one arhitectual question i
> | am not clear on. In fact i cant find a clear answer for this anywhere.
> |
> | One of the pillars of SOA dictates that schema should be shared, and
> | not the class, but this is hard to implement in an environment where
> | WCF is used to communicate between web and middle tier of the same
> | group. Meaning using WCF as transport mechanism between local tiers
> | where the same business objects are widely used.
> |
> | If i have a common Trade object within my application framework, I use
> | it everywhere, on all tiers with and without web services. So the
> | problem here is, that if each webservice creates a proxy with its own
> | version of Trade, there will now be multiple instances of Trade
> | defined each in different namespace:
> |
> | MyCo.BusinessObjects.Trade
> | MyCo.Services.TradeManagement.Trade
> | MyCo.Services.TradeLookup.Trade
> | etc...
> |
> | of course if a Trade is looked up using TradeLookup service, and than
> | attempted to be passed into TradeManagement service it will cause a
> | problem since they are different objects as far as the framework can
> | tell.
> | NOT TO MENTION if one property on Trade changes, all of those service
> | proxies have to be regenerated now.
> |
> | so what i've been doing, is generating regular ws proxy, and than
> | going in and removing all business objects from its definition, and
> | adding a namespace where they are located so that all services would
> | be usnig the MyCo.BusinessObjects.Trade.
> | There is also a library from Think Tekture that will allow you to
> | generate the proxy dynamically, and use whatever objects you choose
> | with it omitting their serialization.
> |
> | To summarize i do not wish to maintain multiple instances of the same
> | class. My question is, what are some ways to address this using WCF.
> |
>
>
 

My Computer

S

sonic

#4
thank for your post.
I can't say that i see alot of convincing arguments in it other than
"this is the new way of thinking" and that this is a "tenet" in the
post below yours. and i did read about the tenets but my book at least
did not explain full reasoning behind that one... there is no
question, that if you're creating your architecture with the intent to
be consumed by external entities you have to go the schema way, i am
not questioning that.
You said that you find it rare that you can actually use the type on
both sides, but in the last 3 years of my experience with local
tiers.. i've been completely re-using the types on both sides.
Additonally i've consumed web services from different platforms, and
there was a need to use proxied objects of course.
here are my reasons for wanting to use shared assembly.
1.
object version collissions
If the same object is generated in a webservice.. you can't simply get
it using your framework, than pass it off to a webservice. or get it
using service A and pass it off to service B. you will always be
forced to copy all the properties upon every call. say you add a new
property to your framework object.. now you have to change all the
places that make the conversion between your object and the web
service objects, and webservice A version to webservice B version
conversion.
So if i have a simple Trade object, now i have to maintain multiple
identical copies of it.
2.
smallest change to my object ( Trade ) will require me to re-generate
all service proxies, and all places where my object is translated from
one version to the next

i'd like to know how this is addressed in WCF? other than.. its a
tenet :)

thinktekture had a nifty solution for this with their proxy factory.
generating proxies dynamically and having the ability to specify what
exactly to serialize etc.. so local services would be identified by
nothing more than simple interfaces.


On Apr 12, 12:33 am, "William Stacey [C# MVP]"
<william.sta...@gmail.com> wrote:
> I have also read and thought about these issues lately. My current thinking
> is that once your sold on soa (and wcf), you need to throw the shared
> assembly stuff out the window and come to grips with the fact that we need
> to cut/paste or gen client side classes even if they are exactly the same.
> The whole point is not to share clr types (e.g. Remoting), but *only
> contract. So we are free of implementation and binary details. If not, we
> always end up down a bad path. Your client is a client...does not matter if
> it is local or remote, hosted in IIS or self hosted. If we do it right, we
> can move that same client code assembly and leverage it all over the
> place(remote, console app, win app, service, etc). So there is a small tax
> upfront, but it pays dividends the whole life of app. I think we need to
> wear two hats during development. When your writing the client, you need to
> forget you wrote the service (which is not easy). Pretend someone else
> wrote it and just gave you the Mex link. In that case, you will be writing
> client totally loose-coupled using just the contracts and interfaces and end
> up on the good path. That is my current thinking anyway. Besides, I find
> it rare that you can actually use the same type on both sides as
> implementations have different goals. The pure data transfer objects (DTO)
> that have zero implementation are no big deal to cut/paste anyway and your
> still free to extend them at either end or both as long the contract stays.
> So you get a lot more flex in many ways then being tied to a clr type.
>
> --
> William Stacey [C# MVP]
>
 

My Computer

W

William Stacey [C# MVP]

#5
It's hard to hit all pros/cons in a single post, but I'll try to show some
things I normally run into right away.
Lets pick something fairly common and easy to reason about - a Job. A
service contains and manages Job objects. A
client can view and add jobs. Up front, I am pretty sure I am going to need
a JobID, a Command string, and probably a
RunCount. To keep it simple, that is all we will add for now. So I know, at
least, we need 3 fields in the class to
be passed between client and service: "int id", "string command", and "int
runCount". So I add [DataMember] to the
fields I need in my contract as shown in Server and Client Job classes
below.

Soon after I start writing the class, I figure out pretty quickly the same
class on both sides is not going to work.
Or maybe I could force it to work, but would need to make compromises I
don't want to make. For example, because it is a
service with multiple clients, I am pretty sure I need to deal with sync
issues and possibly deal with things like locks, volatile,
or Interlock. I am also pretty sure I will want different helper methods on
the client side. So I add a syncRoot object
in the server class and also a static "nextID" field so I can get unique job
IDs on the server end. These fields are
not required on the client side, because they are server implementation
details and I don't want or need those exposed
to the client consumer. I also realize my property accessor needs are
different. My server needs to update RunCount,
my client does not. So I can make the runCount field volatile and add an
internal setter - another two things
the client does not need in my case. The ctor needs are also different. On
the server, I require at least a Command
string so I don't expose an empty ctor, but require ctor(string cmd). On the
client side, I don't care how it constructs a Job, as long as the
fields I need come across the wire and fit the contract. So the client has a
public ctor() with public fields (not something I would do)
it can set as needed. Moreover, because I am not bound to a CLR type, I am
free to add other instance methods
to the client or server classes per my needs. My client needs to override
ToString() in a special way. I also
want to add a ToXml() method on the client class for something else my
client is doing for local logging or display.

So the pros are many to name a few:
1) field modifiers can be different (i.e. private, public, internal,
volatile, etc) on either end. Can't do that sharing clr types.
2) I can add different static fields on either end as implementation
dictates. Can't do that sharing clr types.
3) Class names can be different as long as the contract namespace matches
(e.g. I may require different naming stds). Can't do sharing clr types.
4) I don't need to expose a public ctor(). WCF serialization does not
require. Remoting requires a public ctor().
5) Ctors can be different on either end. Can't do that sharing same clr
type.
6) I don't require public properties with both a getter and setter. I can
use private fields and setup Properties
as needed. Can't do that sharing same clr type.
7) I can add an ExtensionDataObject field to both sides to allow versioning
on both sides. Client and server classes
do not need to perfectly match over time. Great flexibility.
8) Others I can't think of at the moment.

Cons:
1) Need to create client classes. Not sure if we can peg this as a con, as I
think this shows we really need to do that anyway.

I have run into (at one point or another) all those road-blocks with other
techs (Remoting, WSE, etc). If you never run into any of this, let us know
how your doing it. Cheers.

// Server Job
//
[DataContract]
public class Job
{
private static int nextID;
private readonly object syncRoot = new object();

//[DataMember] ExtensionDataObject extensionDataField;
[DataMember]
int id;
[DataMember]
string command;
[DataMember]
volatile int runCount;

public Job(string command)
{
this.command = command;
this.id = Interlocked.Increment(ref nextID);
this.runCount = 0;
}

public int ID
{
get { return this.id; }
}
public string Command
{
get { return this.command; }
}
public int RunCount
{
get { return this.runCount; }
internal set { this.runCount = value;}
}
}


// Client Job
//
[DataContract]
public class Job
{
[DataMember] public int id;
[DataMember] public string command;
[DataMember] public int runCount;

public Job() { }

public override string ToString()
{
return "I override Client's ToString() to fit my client needs.";
}

public string ToXml()
{
return "xml";
}
}

--
William Stacey [C# MVP]
PCR concurrency library: www.codeplex.com/pcr
PSH Scripts Project www.codeplex.com/psobject


"sonic" <sonicsoul@gmail.com> wrote in message
news:1176393210.449064.283570@q75g2000hsh.googlegroups.com...
| thank for your post.
| I can't say that i see alot of convincing arguments in it other than
| "this is the new way of thinking" and that this is a "tenet" in the
| post below yours. and i did read about the tenets but my book at least
| did not explain full reasoning behind that one... there is no
| question, that if you're creating your architecture with the intent to
| be consumed by external entities you have to go the schema way, i am
| not questioning that.
| You said that you find it rare that you can actually use the type on
| both sides, but in the last 3 years of my experience with local
| tiers.. i've been completely re-using the types on both sides.
| Additonally i've consumed web services from different platforms, and
| there was a need to use proxied objects of course.
| here are my reasons for wanting to use shared assembly.
| 1.
| object version collissions
| If the same object is generated in a webservice.. you can't simply get
| it using your framework, than pass it off to a webservice. or get it
| using service A and pass it off to service B. you will always be
| forced to copy all the properties upon every call. say you add a new
| property to your framework object.. now you have to change all the
| places that make the conversion between your object and the web
| service objects, and webservice A version to webservice B version
| conversion.
| So if i have a simple Trade object, now i have to maintain multiple
| identical copies of it.
| 2.
| smallest change to my object ( Trade ) will require me to re-generate
| all service proxies, and all places where my object is translated from
| one version to the next
|
| i'd like to know how this is addressed in WCF? other than.. its a
| tenet :)
|
| thinktekture had a nifty solution for this with their proxy factory.
| generating proxies dynamically and having the ability to specify what
| exactly to serialize etc.. so local services would be identified by
| nothing more than simple interfaces.
|
|
| On Apr 12, 12:33 am, "William Stacey [C# MVP]"
| <william.sta...@gmail.com> wrote:
| > I have also read and thought about these issues lately. My current
thinking
| > is that once your sold on soa (and wcf), you need to throw the shared
| > assembly stuff out the window and come to grips with the fact that we
need
| > to cut/paste or gen client side classes even if they are exactly the
same.
| > The whole point is not to share clr types (e.g. Remoting), but *only
| > contract. So we are free of implementation and binary details. If not,
we
| > always end up down a bad path. Your client is a client...does not
matter if
| > it is local or remote, hosted in IIS or self hosted. If we do it right,
we
| > can move that same client code assembly and leverage it all over the
| > place(remote, console app, win app, service, etc). So there is a small
tax
| > upfront, but it pays dividends the whole life of app. I think we need to
| > wear two hats during development. When your writing the client, you
need to
| > forget you wrote the service (which is not easy). Pretend someone else
| > wrote it and just gave you the Mex link. In that case, you will be
writing
| > client totally loose-coupled using just the contracts and interfaces and
end
| > up on the good path. That is my current thinking anyway. Besides, I
find
| > it rare that you can actually use the same type on both sides as
| > implementations have different goals. The pure data transfer objects
(DTO)
| > that have zero implementation are no big deal to cut/paste anyway and
your
| > still free to extend them at either end or both as long the contract
stays.
| > So you get a lot more flex in many ways then being tied to a clr type.
| >
| > --
| > William Stacey [C# MVP]
| >
|
 

My Computer