Dec
29
2009

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

 

Dec
24
2009

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.

Dec
16
2009

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.

Dec
7
2009

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

Dec
3
2009

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.

Dec
3
2009

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.

Nov
18
2009

A guide to new features of WCF RIA Services

This is an exciting day, everyone can now get their hands on the brand new WCF RIA Services.  Here is a quick guide to some of the new features in WCF RIA Services as well as my personal guidance on how you can use the new features.

The new name

OK, WCF RIA Services has now replaced .NET RIA Services. I know I have talked about the ADO.NET Data Services integration but it turns out that RIA Services has gone beyond that (it has gone plaid!) and it now fully a WCF service. By default, your DomainService is now exposed as a standard WCF service using binary encoding. Sweeeeet!

Stay tuned to Saurabh Pant's blog for more information on how WCF is used by WCF RIA Services.

New rules for Error Handling

This is probably the most important change to understand while converting to the new WCF RIA Services. If errors come back from a SubmitOperation, InvokeOperation, or LoadOperation and is not handled by us then an exception will be thrown. This stops the problem where people new to RIA Services try to Submit or Load and never get an error, they will now get an exception. This can be a breaking change if you have errors coming back from the server that you were not previously handling.

Compositional Hierarchy

This is a big change for people who need real parent/child hierarchies in their code. For example, with a compositional hierarchy the parent’s HasChanges will be true if the child has been changed. However, I think a question that needs to be answered is what the default setup should be. My guidance here is that if you need composition, use composition. If you don’t need composition, or if you don’t know if you need composition, then don’t use composition. The default no-composition model is more flexible and has the potential of having better performance.

Inheritance Support (VS2010 Only)

This has been one of my biggest feature requests. I am extremely happy to say that not only does WCF RIA Services support inheritance, but the team has gone way above and beyond the level of support that I would have been happy with. They really did an incredible job and it is a real testament that Microsoft is listening to us.

Presentation Model

This is huge addition to WCF RIA Services and I don’t think the potential for this feature is really fully understood yet. I think there is going to be a tendency by some people to think that “Best Practices” would be to always use PM for all entities. I don’t think this is the case, it is easy to replace a regular entity with a PM entity without having to change the client so I think the better model is to mix PMs in with regular entities as you need them.

Domain Data Source Changes

I am not an expert in the use of the DDS. Personally, I don’t use it but I know that a lot of people do. The new version of the DDS has the bugs worked out and some simplifications made. Stay tuned to Jeff Handley’s blogfor all of the details.

Nov
18
2009

Updated ApplyState/ExtractState Library

Export more blog entries this week. I will be putting up my guide to the major new features after todays keynote.

In the meantime, here is an updated ApplyState/ExtractState refactored to use the EntitySet instead of the EntityList. I will put up a VS2010 version as well tonight.

RIAServicesContrib2008.zip (235.60 kb)

Sep
8
2009

Interlude 2 - Diagram of MVVM and RIA Services

I promise that the rest of DomainClient will be posted tonight, but John Papa just posted up a very easy to read overview of MVVM. I couldn’t help doodling on his graphic to indicate one way you can map RIA Services to MVVM. As always, I will be hitting these concepts in more detail later.

RIAInMVVM

Note: My crudely drawn lines are trying to show that the DomainContext is taking the place of the two original links.

Sep
6
2009

Interlude – Entities do not have children

Since this is the first interlude, let me explain what an interlude is. I have the main series of articles for this blog planned out, but every so often I will feel the need to jump ahead and give a small sample of what I will be posting about in the future. This can be triggered by a tweet, a post in the message boards, or a passing thoughts catches my fancy.

This particular interlude is about terminology. In RIA Services, every entity should be considered a top level entity. There is no such thing as a parent child relationship in RIA Services; all entities are equal to each other. The hows and whys of this I will cover in the EntityContainer/EntityList series. The point is, the correct terminology should be Entity and Associated Entities, not Parent and Children.

Why is this important?

When we talk about a parent/child releationship there are certain preconceptions we bring to the table. For example, we would expect that the child cannot exist without the parent. We would call such an object an “orphan”. In RIA Services, as there are no children, there are no orphans. If you delete the “parent” the “children” are still tracked in their respective EntityList, all that happened is that the key value that uses to be shared with the deleted entity was cleared severing the association. Granted, you may or may not fail a foreign key check when you get back to the database but that is a matter of correct programming.

This goes back to swo’s question back on the EntityCollection where he asked why the Add and Remove methods were designed in the way that they were. The answer is here in the question of naming. If you use the words parent and child then removing the child from the parent would seem to imply that the child should be deleted. However, if you use the words Entity and Associated Entity that removing the Associated Entity from the Entity would indicate that you are simply severing the association. As are most things are in programming, it is all about finding the proper names for things so that we can correctly understand concepts.

Ok, one thing on why RIA Services is designed this way

RIA Services is actually designed to work a lot like a database does. If you created a SQL Database where all of the foreign keys were nullable and you had cascading turned on you would have something that would act a lot like RIA Services does. That database design would have the virtue of being able to model and other database design that you can come up with in SQL Server. Just something to think about.

(Do not actually go and design a database that way, what works really well for a data model works horribly for an actual database.)

Month List