ToC for the Book Club RIA Services Application

A guide to what is demonstrated in the RIA Services Book Club application, and an index to related blog posts that dive deeper into the application and concepts.

Earlier this week, I published the RIA Services Essentials project on CodePlex to share some sample code. The first sample included is an updated version of the Book Club application.

This application has become sort of a reference application. It was written to demonstrate some aspects of writing a semi-real-worldish application (note that it is still very much a demo app), but more importantly, demonstrating how you can use RIA Services effectively by going beyond the basics. As such, it isn't meant to be a HelloWorld app, which I agree would be useful. This post is a sort of guide for what is in the sample.

Here is a list of what the application demonstrates:

  • Entity framework data model with one-to-many and many-to-many relationships as well as use of stored procedures
  • Local data model augmented/mixed with a web service-based data model (in this case Amazon).
  • CRUD and more (queries, insert, update, delete, as well as named update methods, and invoke methods)
  • Use of convention and configuration for identifying CRUD operations
  • Validation (field level, entity level, operation level, change-set scoped, server-only validation, async validation)
  • Custom authentication (i.e. using your DAL/user table, rather than asp.net membership)
  • Authorization (including custom authorization rules)
  • Using authentication service and your User object in server code
  • Usage of DomainServiceFactory
  • Exposing reference data
  • Presentation model for defining custom (non-DAL) types for use between client and server
  • Shared code between client and server for validation rules
  • Query limits, and caching
  • Using RIA Services with MVVM on the client
  • Adding computed properties on Entities on the client along with propagation of change notifications
  • "More" style paging (as seen for example on twitter.com)
  • Display of pending changes, validation errors
  • Reference data used to fill lookup dropdown lists.

Book Club App Screenshot #1
Book Club App Screenshot #1

Here is a list of things on my mind to include over time:

  • Using Fluent metadata
  • Unit testing of server code and client code
  • RIA Service class libraries
  • Linq To SQL based data model or a custom DomainService base class
  • Additional clients (like the Windows Phone client I demo'd at MIX10)

Separately, I'll be publishing blog posts over time that cover specific aspects of the application in some detail, and will be updating this list, so you have an index to go by:

I guess I need to publish a couple more topics soon. On that note, if someone builds upon or extends the application in interesting ways, that would be awesome! I'd be happy to link to your post from here.


Added (6/9/10): There is also some related video content:

  • You can watch the MIX10 presentation.
  • Dinesh presented a variant of the same app concept and data for the RIA Services v1 release on SilverlightTV (episode 28)
  • On Silverlight.TV, I did a presentation on Validation (episode 18). It uses a different app, but shows some similar code.

Posted on Wednesday, 6/9/2010 @ 12:32 PM | #Silverlight


Comments

20 comments have been posted.

Ben Hayat

Posted on 6/9/2010 @ 2:43 PM
Nikhil, could you please cover the RIA Class Library as your next topic when RIA is being used with Prisim (multi modules) project?

Thanks!
..Ben

Ben Hayat

Posted on 6/9/2010 @ 2:52 PM
BTW, you also did a nice video with Silverlight TV that covers this project as well. You may want to include that link. In fact, I think it's best to watch the video first and then dive into the code. Things will make more sense.

Nikhil Kothari

Posted on 6/9/2010 @ 4:07 PM
@Ben
Posted some video links. Thanks for the suggestion.

As for RIA class libraries, I can make that the focus of the next update to the code, and follow it up with a blog post. I'll probably have a few more basic posts in the interim that don't need any code updates.

However, I am not going to (I think) cover the Prism angle to it, at least for now. The app would need a much bigger update and potentially scope to become a compositional app, where something like Prism or MEF used to load and compose an app out of modules would make sense. I think a different app might qualify much more naturally.

Instead what I want to show with class libraries is the concept that the feature was originally designed for, but never really demonstrated. It is to enable developers to create RIA components that have a combination of client and server halves, just like apps have client and server halves. So its not so much about dynamically loading/composing as much as its about writing functionality that spans tiers and delivering it as a logical single "thing"... I have an example in mind about how I can fit it into the book club scenario... but need to work out the specifics, and of course the implementation.

Ben Hayat

Posted on 6/9/2010 @ 7:09 PM
Nikhil, when I mentioned the usage of RIA & Prism, I wasn't really asking you for writing a big modular app using Prism. But my asking was when someone starts building a modular app, they don't usually use the RIA template with it's STD implementation, however they need to use RIA as a class library to be used among all the projects. So, if you can demonstrate that without the use of Prism, it serves the purpose.
I think your last paragraph may come close to what I'm asking.

Amit

Posted on 6/10/2010 @ 12:19 AM
I could not find the way to use RIA when I am not using database as as a backend. I am going to get the data through COM that is pre written. Please advise any best example for that.

Osku

Posted on 6/10/2010 @ 12:35 AM
-Something I'd like to see is how you implement a confirmation dialog system in this application, an Example is when you're Sharing a book if you try to change the currently selected book and prompt you for example, "Do you wish to the discard the currently unsaved book" instead of just switching the book and losing all changes.
-Another one would be a quick and easy way to implement something similar to the [Editable(false, AllowInitialValue = true)] attribute on your BookEditor control (maybe you shouldn't be allowed to change the amazon id after it's been validated and saved once).

Nikhil Kothari

Posted on 6/10/2010 @ 7:26 AM
@Amit
Your operations can call into any service or component to get data from. In your case, just derive from DomainService directly, and call into your object.

@Osku
I'll look into the confirmation prompt. Good idea.
As for respecting [Editable] etc. I fully agree with the scenario, but rather than do this type of stuff in a BookEditor control, I would rather be writing a general purpose EntityForm control. I've always wanted to do that, but its not the most trivial undertaking. I'll put it on the list, but I don't think it will happen immediately.

Frans Adi

Posted on 6/10/2010 @ 1:47 PM
Hai Nikhil, I have looked into the latest source code from codeplex and I found some interesting changes since your MIX10 demo.
How did you combine the ViewModel into the XAML behind-code? (Example: BookShelf.Model.cs behind BookShelf.xaml)
Thanks for the great reference application.

Osku

Posted on 6/10/2010 @ 10:35 PM
Concerning [Editable()] the suggestion was not to implement the attribute but an example would be binding the IsNew property on your book to IsReadOnly on the amazon id box through a InverterConverter (Oh I really hate that word). Then the box would be editable until the IsNew == false, of course if you come up with a better solution that would be awesome.

Hmm, instead of something large as EntityFor,m something silly like EntityTextBox wouldn't be a bad idea either.


@Frans
I looked into this earlier and it's rather annoying so I'll just answer it for you but maybe Nikhil has a better way of doing it, you need to edit the project file and add a <DependantUpon> tag to the files you want to link as codebehind.

Here's a example from the app in BookClub.csproj:
<Compile Include="Pages\BookShelf.Model.cs">
<DependentUpon>BookShelf.xaml</DependentUpon>
</Compile>

KK

Posted on 6/11/2010 @ 6:15 AM
Your framework Silverlight.FX in the download page says: "Silverlight.FX is an application framework for building Rich Internet Applications with Silverlight 2" There is also a download for SL 3. Is there one for SL 4? Is it appropriate to use with SL 4 or does SL 4 now has some features that Silverlight.FX was trying to feel a gap for in SL2?

Nikhil Kothari

Posted on 6/11/2010 @ 9:09 AM
@KK
SilverlightFX is still useful. I intentionally did not use it in this sample, even though I wanted to, just to avoid external dependencies.

I will have an SL4 version at some point with some improvements, but I believe the current version should also work. It should say Silverlight 2+ if it doesn't already say that.

rlodina

Posted on 6/11/2010 @ 12:27 PM
Hi Nikhil - thank you for your effort.

I don't remember exact - where I see a piece of code, writed by you, regarding of working with data in offline mode - you saved EntitySet in IsolatedStorage - what a great ideea.

I am not sure if Book Club app need this features (to put this on TOC)

Nikhil Kothari

Posted on 6/11/2010 @ 6:47 PM
@rlodina
You're referring to my Mix09 demo showing offline scenarios with RIA Services. The book club app doesn't do any offline scenarios, at least right now, but I certainly want to get those supporting bits updated to run against v1, and have them be part of the codeplex project.

Kris

Posted on 6/15/2010 @ 11:39 AM
I second Riodina, offline capabilities.

I did try to load up the Mix 09 demo with the offline storage, but running SL4 & vs2010 I could get it to work.

I would love to see a similar method implemented in silver light 4

Andries Olivier

Posted on 6/22/2010 @ 2:23 AM
Nikhil,

Really enjoying your blog / samples. Just a question about caching on the BookClub:

Instead of:

[OutputCache(OutputCacheLocation.Any, 3600)] on the domain context, would it be feasible for a more robust caching mechanism allowing for manual purging / clearing, to rather use something like this:

public IQueryable<MyEntity> MyFunction()
{
IQueryable<MyEntity> items = null;
string key = "Key:MyFunction";

if (HttpContext.Current.Cache[key] != null)
items = (IQueryable<MyEntity>)HttpContext.Current.Cache[key];
else
{

items = ObjectContext.MyEntity.
OrderBy(c => c.MyColumn);

HttpContext.Current.Cache.Insert(key, items, null,
DateTime.Now.AddSeconds(3600), TimeSpan.Zero);
}

return items;
}

I'm fairly new to EF4 and RIA Services, and would like to know if caching would be more scalable firstly, and secondly what is the best practices specific to LINQ (using IQueryable)?

Regards
Andries

Nikhil Kothari

Posted on 6/23/2010 @ 10:45 AM
@Andries Olivier
Yes, you can do things programmatically instead of declaratively.
In fact, what you're doing is storing something in general purpose cache which has no declarative equivalent. The declarative mechanism is around output cache which is more specialized scenario (which can also be set up programmatically).

Aside: Don't use HttpContext.Current, as it gets in the way of testability. Instead use
HttpContextBase httpContext = (HttpContextBase)ServiceContext.GetService(typeof(HttpContextBase));

Aside #2: Don't ever story IQueryables into cache. Execute the query and store the results.

Mahesh

Posted on 6/30/2010 @ 7:14 AM
Hi Nikhil,

When the VB.Net code for this application will be available?

Converting simple code piece like below using third party utilities is very frustrating, at times wrong.

if (SelectedBook.IsNew) {
_bookShelfContext.BookExists(SelectedBook.ASIN,
delegate(InvokeOperation<bool> operation) {
if (operation.Value) {
ValidationResult duplicateError =
new ValidationResult("This book already exists in the book club.", new string[] { "Title" });
SelectedBook.ValidationErrors.Add(duplicateError);
}
else {
EndEditing();
}
}, null);
}
else {
EndEditing();
}

Irfan Syahputra

Posted on 7/9/2010 @ 9:11 PM
Hi nikhil,
how to add view model class inside xaml file, sorry iam first time use visual studio

Nikhil Kothari

Posted on 7/11/2010 @ 10:17 PM
@Mahesh
No plans for doing a VB.NET version - sorry. However, it would be great if someone in the community can volunteer to create one if there is interest.
I suspect the code snippet you're having difficulty with is related to anonymous delegates. You can do them in vb9 - see http://stackoverflow.com/questions/727550/anonymous-delegates-in-vb-net-pre-vb9

@Irfan
There is no automated way to do it (not that I know of). If you look at the .csproj, you'll see the .model.cs is marked as dependent on the .xaml file. That is what creates the nesting in visual studio.

jsp3536

Posted on 8/4/2010 @ 11:33 AM
I was wondering if you could answer how an app should beak down domain services. I have seen some discussion in threads on this topic and I am unsure on where or what the guidelines are on this topic. Should a separate domain service be created for every Silverlight page in an app or would you used just one domain services?
Post your comment and continue the discussion.