The Elephant and the Silverlight

Thoughts and analysis of Silverlight for business applications

Page List

    Thoughts on Modular WCF RIA Services

     

    I had an interesting question tweeted to me yesterday from Ariel Ben Horesh requesting my opinion on sharing data models between Prism modules using WCF RIA Services. My opinion is that there is a 1:1 relationship between an editable DomainService/DomainContext and a module. My reasoning is that both a module and a DomainContext are a single unit of work. I would further suggest that is you have a module that requires two separate editable DomainContexts that you actually have two separate modules.

    Notice that I keep saying “editable DomainContexts”. If you have a DomainContext which has only read only entities then I see no problem with putting that DomainContext in a shared library referenced by multiple modules. You can even put in ExternalReferences from your modules DomainContext to the shared DomainContext if you really want. I usually discourage the use of ExternalReference as I feel that people misuse the functionality to attach two editable DomainContexts to each other but I don’t see a problem with a non-editable DomainContext.

    Ariel then asked how events/commands could be used between the modules using entity data when the modules are not sharing data and, after I gave my answers, asked for some examples. In response, I created this Sample Project which creates several pseudo-modules. It is not using MEF or Prism to create actual modules, just standard WCF RIA Services Class Libraries which are representing modules.

    One module, ParentModule, has a model which contains only the Parent entity. ParentModule represents the primary module of an application, the one that works with the “root” table of a database. The Parent entity has a related Child entity which has a ChildTypeID. The other two modules (ChildHeightModule and ChildWidthModule) represent modules that modify only one type of Child entity. One of the Child modules has the Parent entity in its model and the other does not.

    Communicating by Key

    The primary way of communicating between modules is to pass primary keys. For example, if the application has a Parent entity and wants the Child modules to load the Child entities of that Parent then it simply needs to pass the ParentID to the two child modules which can then easily load data based on the ParentID.

    Communicating by Interface

    Sometimes just passing keys around isn’t good enough and you need access to entire entities between different modules. The solution to that is to implement shared interfaces on your entities. If you check my sample project you will find that I implement several interfaces using generics. Using the shared entities I could pass an entire Parent entity from the ParentModule to either of the Child modules as an IParent. The limitation of the interface versions of the entities is that they cannot interact with the local module’s DomainContext (i.e. you can’t set the Parent property of the Child to the IParent entity).

    I use this technique extensively and it really helps when created shared code to do operations on the different entities. For example, both the ChildWidth and ChildHeight entities implement the IChildDimension interface. If I wanted to create an IValueConverter that operated on objects that implement IChildDimension that is a really easy thing to do. I could also pretty easily have a module that gets sent all  of the IChildDimension entities from all currently loaded modules and displays them all in a grid.

    Communicating by Cloning

    The third option is to use the WCF RIA Services Contrib ApplyState/ExtractState extensions to clone the entity between the DomainContexts of two different modules. Both ParentModule and ChildWidthModule have the Parent entity. They are different types in different namespaces but they both have the same DataMember properties. This means that the IDictionary<string,object> extracted from Parent in the ParentModule can be applied to a Parent entity in the ChildWidthModule. This is not recommended. Extracting the state from one module and applying it in another is inherently brittle and can create a maintenance nightmare. However, I am sure that someone will hit a situation where cloning is the only solution that works for them so I include it here for that person.


    Categories: RIA Services
    Permalink | Comments (7) | Post RSSRSS comment feed

    Comments

    Community Blogs

    Thursday, December 24, 2009 1:20 PM

    trackback

    Silverlight Cream for December 24, 2009 -- #762

    In this Christmas Eve in Phoenix Issue: Richard Waddell , Kirupa , Douglas Starnes , Nigel Sampson ,

    topsy.com

    Thursday, December 24, 2009 1:29 PM

    pingback

    Pingback from topsy.com

    Twitter Trackbacks for
            
            The Elephant and the Silverlight | Thoughts on Modular WCF RIA Services
            [riaservicesblog.net]
            on Topsy.com

    uberVU - social comments

    Wednesday, December 30, 2009 6:19 PM

    trackback

    Social comments and analytics for this post

    This post was mentioned on Twitter by brada: @slcolinblair chimes into the modular RIA Services\Silverlight conversation  http://bit.ly/7nJLvl .  Well done as usual.

    Pontus M Sweden

    Monday, January 18, 2010 3:47 AM

    Pontus M

    Thanks for sharing your thoughts on modular design with Ria. Very informative!

    It would be nice to hear your opinion on another scenario. We are currently developing a Silverlight application using Ria and Prism. We have split up the application in several Prism modules to cut down loading time and to be able to develop modules in different teams. However, our current data model consists of about 20 entities that are all more or less related to each other. My conclusion is then that we should have one Ria domain context for all of this data to avoid the hassle with configuring cross domain references.

    Now I must be missing something because it just feels a bit messy to put all of the server side data access methods in one big domain service class on the server. Sure, you can split it up in several partial classes and keep things in different files but it still feels like a bit of a hack. Maybe this is the wrong way to do it?

    Another solution I've considered is to create one domain context per view that the user is working with. This makes more sense since you probably want to submit only the data changed in that view when the user presses the save button. The problem is that you then end up with entities being spread out and loaded in different contexts (possibly fetched from server more than once), and you need to make sure you refresh the other contexts when one is saved. Seems to involve lots of extra house keeping...

    Any input is welcome!

    Colin Blair United States

    Monday, January 18, 2010 10:15 AM

    Colin Blair

    @Pontus, I agree that it does feel a bit messy to me. The real question you need to answer isn't modules or views, it is transactions. The DomainContext's SubmitChanges is a single transaction and you can't share a transaction across multiple DomainContexts as Silverlight doesn't have distributed transaction support. Lets use your example of an entity that can be loaded into multiple views. If that entity can only be edited in one place AND you can edit in that one place without needing to rollback the change if some other module/view fails to save then you can use an ExternalReference to connect the two different DomainContexts. If you do have a transaction dependency then the entities must be in the same DomainService and the same DomainContext instance.

    Pontus M Sweden

    Tuesday, January 19, 2010 5:31 AM

    Pontus M

    So we really need to think about groups of entities that are edited and saved together and put them in the same domain service. And we need to work with external referencing other entities. This makes it a little bit more cumbersome for the client since it needs to work with several domain contexts and ensure all data needed is loaded, but I guess we can live with that.

    Most of our entities are only edited from one place so I think we can partition our domain service wisely.

    Many thanks for your help!

    245.tvshowzone.com

    Thursday, May 20, 2010 12:13 PM

    pingback

    Pingback from 245.tvshowzone.com

    560sl Aftermarket Prices Cl55 Amg, C55 Heater Fit Cl55 Amg

    Add comment


    (Will show your Gravatar icon)

      Country flag

    Click to change captcha
    biuquote
    • Comment
    • Preview
    Loading