Do you do SOA?

OK, the title is buzzwordy and doesn’t mean much but here is the question I want to pose as we evaluate the relative priorities of various multi-tier scenarios in DLinq.

Do you use the same type on mid-tier and on presentation / web-service client tier?

I have seen many discussions about how some people want to use the same assemblies on mid-tier and presentation tier (or even on web-service clients). I personally think that the two should be designed separately and should not be the same unless there is a justification for it. What you retrieve from database and use on your trusted mid-tier may be quite different from what you expose to a large number of clients – whether presentation tier of your app or consumers of your web-service sitting in another organization.

However, there are others who passionately argue that it is the same data everywhere and so the ability to use the same objects on multiple tiers is critical. DataSet and typed DataSet users in particular often champion this cause and love the fact they have a single package that captures data retrieved from DB, data sent over the wire, data bound to forms, data returned to the mid tier and data persisted to the DB. Some even go beyond data and claim that the minimal attached behavior is also common – e.g. validations.

My question is – do you have good scenarios where having the same objects really makes sense? Or are these more corner cases? Have the SOA priests just missed the practicality of such scenarios or are they right about bashing tight coupling?


Comments (7)

  1. I don’t use Datasets, and I see the value of a single DAL approach.

    If there are stuff that I don’t need to expose to the WS, that will be in the model. As a security decision.

    I see no point in maintaining two DALs and two models.

  2. Dinesh,

    The way I see it. OO is a local phenomena. So does ORMs. So does DLinq should be. I believe in SOA tenet: Services share schema, not class. Your service client can be Java that has no idea about .NET types!

    Objects to be passed around between Service provider and service client is DTO (Data Transfer Object) that is not necessarily Domain Types at service provider side. Service provider and service client can make their own representation of the Domain Types as long as conform to an agreed schema.

    However, in scenarios where service provider and service client work with exactly the same data, it would be practical to have DLinq based objects to be passed around, detect changes, etc.

    But… I’m afraid DLinq will become bloated just like Datasets.

  3. Thanks Ayende and Norman for your comments.

    Norman, it is more than not sharing classes. DLinq will not assume sharing of types – that is the easy part. What is harder is trafficking original values and the actions to be taken on SubmitChanges() (i.e. insert/update/delete)

    You are right in pointing out the degenerate case where the data happens to be the same and hence types could be (but don’t have to be) shared.

    We do place a premium on interop. But we can’t leave the 3-tier, new app, designed-from bottom-up to be a single app scenario. That is what this conversation is really about.

  4. Hi Dinesh,

    I agree completely with your opinion here. Because it takes longer time to convice my opponents that they are wrong than it does to implement the support that would please them, I have added the possibility for sharing the Domain Model between the client and the server, but in all honestly I think you are 100% correct in your observation that this is normally way to tight coupling between client and server


  5. Marc Stevens says:

    Hi Dinesh,

    Comment about: “Do you use the same type on mid-tier and on presentation client tier?” If ‘(presentation layer(p) maps percentage of data layer(d)’ then typically [Crud (customer,…)] (p)90%(d) [Crud (invoice,…)] (p)70%(d) [Browse] (p)10%(d). Of course, this is a very gross estimation but gives some direction and makes the point that the answer to your question is probably application type dependent. In addition, what might happen is that (for many different reasons) the presentation layer exhibits additional objects that are ‘view entities upon base entities’. From an implementation viewpoint, when full control is granted over the usage of interfaces and classes in the different application tiers, somewhat different interfaces may be used in these different layers upon the same classes (f.i. in order to discriminate between validation rules).

    Comment about: “What is harder is […] the actions to be taken on SubmitChanges() (i.e. insert/update/delete)”  [especially in case of database rule violation]. SubmitChanges() is a DataContext method. If rules are violated upon performing that operation, that’s the problem of DataContext based upon inconsistencies in referenced object. The fact that the same object (instance, let alone type) exercises different validation rules depending on its context does not disturb me. Let me take some examples. In a “four eye procedure (banker’s world)”, an object must be validated by a second person. Obviously, there are object rules being invoked when the object is operated upon by the first person and additional/different object rules when the same object is operated upon by the second person (context-dependent validation rules). More generally, in the context of a long transaction, the same object is manipulated (verified, etc.) differently. As a final example, when objects are processed interactively or in a batch context (e.g. check validation in a bank), they are usually the same objects but different (additional rules) might apply.

    Comment about:  “DLinq Overview document, 4.3 Simultaneous Changes: If you are making changes on a middle-tier or server, the easiest thing you can do to rectify an optimistic concurrency violation is to simply start over and try again, recreating the context and reapplying the changes.” Correct. However, the same types, if ever used in the presentation layer (within a ‘PresentationContext’ to make an analogy), could definitely not be the subject of such rectification behavior in case of rule violation.

    Summarizing: if a ‘conceptual object’ is considered the ‘reference’ provided by business analysis and considering that such object must be mapped to ‘resource-bound’ objects (and contexts), then:

    – There may exist different conceptual object views to be operated upon in the life-cycle of an object (see above); in many middle-sized applications or in such circumstances as a RAD project, it is acceptable to have only one such view and/or resource (except probably for ‘browse’); if required, different ways exists to project the conceptual object upon these views (interfaces, metadata marking, etc., outright splitting of object into (sub)tiers)

    – The mapping between the conceptual object, its views and the object resources is usually subject to projection (the shape of which may vary dramatically based on the application profile, see above); such projection techniques can also be applied between conceptual object views when conceptual object split-up between tiers exist.

    – Whether these different projections (concept/concept or concept/resource) occur with different objects (types or instance, see above) or not is in my experience a matter of application profile, of design style  and of system environment constraints. The latter is certainly true when considering the consequences of the tight WPF data-binding techniques upon the conceptual object (business layer) advocated by its proponents.

    – One approach tends to use run-time techniques based indeed on a single object type or instance, the other one relies more on generation-time techniques in order to maintain the consistency between the split-up objects. I have seen both working equally well (or not ;-).

    Hope it helps,

    Kind regards, Marc.

  6. Jon Miller says:

    Currently, I’m using NHibernate in a Web service to get objects out of a database. I return these objects from web service methods. The only changes that I make to the objects is that I selectively null out some properties to eliminate circular references and prevent lots of objects from being serialized that I don’t want being serialized. I have other web methods that accept these objects as parameters and the objects are then saved back to the database. I would very much like to see this capability in DLinq as well. While it’s true that in some cases maybe you should not have tight coupling like this, I’d still like to see it possible to do.

  7. James Rutland says:

    I have abandoned development of my in-house OR/M because Dlinq has impressed me so much. However this decision is based on the assumption that Microsoft will eventually offer support for the automatic serialization of Dlinq result collections to the remote client that expressed the Dlinq query.

    To put some perspective on this I am very interested in smart client development and I expect 80% of business logic to run at the client in my application. I am also an old-school OO developer and will bulk up my Dlinq entity classes with a lot of businiess logic, I say this because I expect many will adopt Dlinq and regard the result collections as dumb tuple data repositories i.e. new generation strongly typed datasets.

    If Microsoft does implement remote client Dlinq I would like to see a server-side interception mechanism that allows application logic to apply security checks on both the request pre execution and the result set. I would also like the option to indicate to the Dlinq remote-server framework whether I wished the result objects to be instantiated server-side prior to serialization back to the remote client.