The Elephant and the Silverlight

Thoughts and analysis of Silverlight for business applications

Page List

    Fredrik Normén: WCF RIA Services DomainService life-cycle and adding Transactions

    Fredrik Normén just posted up an extremely good blog post on the lifecycle of the DomainService during a Submit operation. Since I had the same subject on my todo list, I am going to cross it off by telling you to go read what Fredrik posted.

    WCF RIA Services DomainService life-cycle and adding Transactions

     


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

    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

    RIA Services Enterprise Business Application: The Movie

    A step by step guide was requested for how I created the Enterprise Business Application from my previous blog entry. The video is rushed as I was fitting it into lunch, I apologize in advance if it is too difficult to follow.

    Part One: http://www.screencast.com/t/NGNiZjg3ZjY

    Part Two: http://www.screencast.com/t/NGJkYTEw

    Part Three: http://www.screencast.com/t/MWQ2MjdiYTct

    Commentary: I made a mistake in Part One when editing the project file. In the second section that I paste in, where it says:

    Include="..\EnterpriseTest.Web\resource\

    the EnterpriseTest.Web needs to be changed to EnterpriseTest.AppServices.Web for both resource files.

    In Part Three I was running out of time (I only get 5 minutes per video from Jing) so it gets disjointed at the end. Basically, just keep compiling, going thorugh the errors, and resolving the references. At the end you should have working application.

    Timeline

    I did not record any audio for the videos. If you can't figure out what I am doing let me know which the file and time code is and I will place a comment here explaining what is going on.


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

    RIA Services Enterprise Business Application Attempt Part One

    A question that has come up a few times on the forums is how the Silverlight Business Application template can be modified to make it more enterprise friendly. This means moving the Authentication DomainService into a separate WCF RIA Services Class Library and removing the RIA Link from the main application. Attached is my first attempt at doing this. What I have done is create a new WCF RIA Services class library named AppServices. At this point, there is no change in any functionality and other then some namespace differences everything should work exactly like the original template did.

    I have several additional changes that I am planning to make. My planned steps:

    1. Refactor the Business Application Template to use a class library (complete)
    2. Build in the MEF links from Brad's example here
    3. Convert the sample project into a Visual Studio template and add to RIA Services Contrib
    4. Prove the template my re-implementing Brad's PDC demo using the new template

    EnterpriseBusinessApplication08.zip (2.11 mb) C# VS 2008 Version

    BusinessApplicationTemplate.zip (2.19 mb) C# VS 2010 Version

    The part I am most worried about is step 3, converting something this complex into a Visual Studio template is not something I have done before and I am not sure what the best method is to accomplish this. If anyone has any tips or blog urls that I should take a look at please let me know. Also, if you disagree with any design decisions I am making let me know. For example, I am not sure about the AppServices name I picked for the project. 

    Thanks to Max Paulousky who wrote an article on CodeProject that solved a problem I was having with getting the WebContext to find the AuthenticationDomainContext.

    Update: There is now a VS2008 version and I improved on Max's original fix by casting to WebAuthenticationService instead of FormsAuthentication so that the code no longer needs to be changed to switch to WindowsAuthentication. That change was made to both versions. Some people are having trouble with errors saying that a DLL isn't trusted. Brad has a blog entry explaining the problem


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

    Bug in the Create DomainService wizard

    In a previous blog post I documented an undocumented breaking change in the DomainService wizard. It turns out that it is really a bug.

     

    When you create a DomainService using the July .NET RIA Services you would get an update that looks like this:

    public void UpdateMyEntity(MyEntity currentMyEntity)
    {
        this.ObjectContext.AttachAsModified(currentMyEntity, this.ChangeSet.GetOriginal(currentMyEntity));
    }

    The new version gives you a version that looks like this:

    public void UpdateMyEntity(MyEntity currentMyEntity)
    {
        if ((currentMyEntity.EntityState == EntityState.Detached))
        {
            this.ObjectContext.AttachAsModified(currentMyEntity, this.ChangeSet.GetOriginal(currentMyEntity));
        }
    } 

    It turns out that the new version is a mistake, not a change that was undocumented in the breaking changes document, and it is causing major problems for people. The recommendation is that all Updates should be modified to remove the If check so that the resulting method looks like the original .NET RIA Services version.


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

    To Share or Not to Share

    One of the really interested puzzles that occurred to me with the release of SL4 and the VS2010 version of WCF RIA Services is what the new ability of .NET 4 to reference SL4 code libraries means to the WCF RIA Services shared file feature. My thinking goes like this:

    1. The shared code feature was created because the Silverlight and Desktop CLRs couldn’t share assemblies.
    2. The Desktop CLR can now reference Silverlight 4 assemblies
    3. Given that the shared code feature is not being removed, there must still be a use case for shared code
    4. The use case for shared code must be uniquely related to RIA Services, otherwise the feature would become part of Visual Studio itself
    5. Given both 3 and 4, it follows that while the shared feature is important, we must be careful to limit our usage.
    The Use Case for Shared Code

    The use case is very simple, RIA Services uses a DAL or PM object and a RIA Services Entity on the client. Those are two completely different objects yet we have business logic and partial classes that we want to share between the two tiers.

    One way to fix this problem might be to apply a shared interface to the client and server side objects. If that interface was defined in a Silverlight class library then both the server and client could share that same interface. Then all of the business logic could be defined within a Silverlight class library and shared between the client and the server. However, creating interfaces and class libraries doesn’t really fit in with the “RAD for Silverlight” image that RIA Services has.

    The shared code feature handles this by copying un-compiled code between projects. This allows the same code to be compiled against two completely different objects (the server side DAL/PM object and the client side Entity) without having having to have any real interfaces. Also, to be frank, for most people putting interfaces on data objects is taking things a little too far.

    The Case Against Shared Code

    I am not going to get too deep into this one. Suffice to say, there is a reason that we use multiple projects that compile into dlls instead of just copying all of the code files for a solution into a single mega project and producing a single mega-dll. The shared code feature is part of RIA Services that Shawn Wildermuth would probably call a “Visual Studio Trick”. It is, much like the metadata file used to attach business rules, a bit of a kludge. I wouldn’t be surprised if the shared code feature doesn’t end up getting ripped out of Silverlight in a few years when some new feature of the CLR gives us a better way of solving the core use cases.More importantly, since the shared code feature is purely a compile time piece of trickery I don’t expect Microsoft to be worrying to much about keeping backwards compatibility of shared files too high on their must do list.

    Great, so what is the recommendation?

    To put it quite simply, for any code that needs to interact directly with both the Entity and the DLR/PM objects you should be using the Shared file feature. Any shared code should be kept as shallow as possible so keep as much of your code as possible in a Silverlight class library that is shared by both the server and client sides of your project.


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