design question regarding generated proxy classes/DataContracts
Hello all,
I have a design question not neccessarily directly related to Indigo:
Let's say I have two services dealing with Customers, both will use a (or the same) Customer class as arguments in a servicemethod like
==
[Serializable]
[DataContract]
public class Customer{
private int _id;
[System.Runtime.Serialization.DataMemberAttribute(Name = "Id")]
public int Id {
get { return _id; }
set { _id = value; }
}
==
Now users of the service can generate a proxy with svcutil and svcutil will generate a Customer class that can be used by the serviceuser somewhat like that:
[System.Runtime.Serialization.DataContractAttribute()]
public partial class Customer : object, System.Runtime.Serialization.IUnknownSerializationData
So far so good, but what if I myself want to create two different clients and also want to create an assembly that is shared between both clients that provides some common methods with Customers. Since both clients have their own generated proxy class they also have their own version of the Customer class, therefore I can't have methods in my shared assembly that work for both client programs just like that.
One solution I thought of was using an ICustomer interface definined in an shared assembly, is that a good idea? If so, is there a way to tell svcutil to generate classes that derive from an Interface I specify? Or what is the recommended approach in this scenario?
Many thanks
Ben
Hi Ben
remember that in soa, you "share schemas, not classes". So, if I'll would recommend that you won't have a shared assembly with logic code inside. But... i must say i like to interpret this on another way.. . Customer class in the server side, is a schema, right ? Not a XSD schema, but It's a schema described in code. In a solution I'm having, I'm redistributing those schemas to public in a "sdk", so they can have the option to use it, IF they want, since they can get my xsds and use them.
In what concerns the methods you mentioned to have some logic, something i didn't undrstand is why they are not in the service side... what kind of things are you wanting to do.. it would be good if you can give us more details
hope it helps
Hi Hugo, thanks for your reply!
The sole motivation for the project I'm working at right now is learning about Avalon and Indigo. Perhaps the main reason why I'd like to share classes not just schemas is that I'm using Indigo just as a convenient way for IPC and am not really thinking the SOA-way...
What I've been doing is:
I've written a little service (indigo hosted in a Windows Service) that grabs stock data from the web and an (avalon) client that communicates with the service via Indigo and also some user controls that display stock price graphs etc.
Both the client and the usercontrols can just have a reference to the generated proxy assembly and this works allright.
The things I was wondering about were:
1. Let's say I want to make my usercontrols more general and have them take IStock references instead of Stock. So I was wondering whether I could make svcutil automatically derive from an interface and thus compile my proxy class automatically in an batch file. Now that i'm thinking about it, this probably doesn't make too much sense since I would need to have the interface defined somewhere in an interface assembly and would have to redistribute that dll.
2. What if I would really offer a webservice that allows users to retrieve stock data and i also want provide a assembly that allows my users to do some statistics with the retrieved data (just as an example, possibly not a good one. i don't want to this on the server for performance and resource reasons, but provide some added value for the users.). I reckon the only way to do this would be to provide an sdk as you're suggesting, the sdk could then contain an compiled proxy and the data classes.
I suppose what i would really like is language support for some sort of implicit interface, so that any class that has the right properties and methods would implicitly implement an interface with those methods and properties. Don't think this is gonna happen though.
Anyways, just thinking about things loudly has helped :)
Thanks
Ben
Hi Ben
Regarding your point 1, maybe you already know, but you can actually generate the proxy (channel) in runtime. you do it through ChannelFactory, like this:
IStock stockSvc =
ChannelFactory.CreateChannel<IStockSvc>();
so, i think your point no 1 is resolved through this...
In what concerts to 2), that's a general architecture issue.. a common one :) I still think that the server should centralize as much as rules/processing as possible, so the best would be to do it on the server. Although, there are times where i do it on the client side, like, for example, input validations.
Let's take an example:
Imagine you have a smart client application (avalon/win), that has a form with some inputs, like, for example, Customer Maximum Debt (CMDebt). Imagine you have a business rule that says that CMDebt can't be more than $100.000 .
Normally, you would have this validation on the form side, even if you have a service layer that encapsulates your business layer.
What i generally do is to load a set of client validations, that i get from the business layer, through metadata.
What this means is that you also face business validation rules as a service from your available services.. and then work with the result as much close from the user as possible to avoid a wrong user interaction model, right ?
What do you think ?
regards
Hi Hugo,
thanks for pointing me to the ChannelFactory class. i'm creating the channel with ChannelFactory now and that's actually quite close to the implicit interfaces I was thinking of. Seems to use a fair deal of reflection internally to accomplish this.
Generally I agree that doing as much as possible on the server is a good thing. Providing input validation rules as a service is a cool idea, i have to admit that so far i've done input validation almost always in client code. But often there still are things that are better done on client side in order to provide a responsive and powerful UI. Personally I'm glad that the general trend seems to be moving away again from thin clients/web apps back to fat/smart clients...
Well, thanks a lot for you input, it has helped!
ben