UserState & knowing when you’re done in .NET RIA Services

by Tom 7. July 2009 17:28

UPDATE: I bumped into Nikhil Kothari on Twitter and he mentioned that the eventing model for DomainContext is changing in the July CTP (going to become a lot more intuitive when dealing with multiple concurrent calls)…

The more time I spend working with .NET RIA services, the more I like it. That said, it’s not without it’s frustrations. Today I spent a good part of the afternoon writing some Silverlight test cases and found myself repeating a stack of awkward, ugly code.

Most of the example code I’ve seen around the web is pretty simplistic and doesn’t deal with DomainContext classes that make multiple calls (submits and loads). I’m sure this will change as ria services mature, but at the moment rich examples are hard to come by.

The issue I was having was tracking which call was returning in two of the main events that a DomainContext raises: Loaded and Submitted. These  events are useful in the sense that they tell you when your call has completed, but if you’ve made multiple calls simultaneously then it’s not easy to tell which call is the one that has raised the event. For instance, when the Loaded event is raised, the LoadedDataEventArgs gives you access to a LoadedEntities property which holds the collection of newly loaded entities. You could then check the type of the first entity in order to see which load call has completed, but this is not a great solution as a call may have returned null (i.e. zero results)

Enter UserState. I actually couldn’t find much documentation on this one, but in a nutshell, it is a parameter of type object that you can pass into load and submit methods of your DomainContext and get back in the LoadedDataEventArgs and SubmittedChangesEventArgs.

On the most simple level you could call a method, say, LoadById() and pass in an int, say 1. When the Loaded event is raised after the call, you get back the LoadedDataEventArgs which now carries a property called UserState which is an int with a value of 1. Nice!

After reading around a bit on the Silverlight forums, I decided on the following approach to streamline things further.

Firstly, I created a delegate in the presenter of my view.

private delegate void CompletedDelegate(EventArgs args);

 

Secondly, I hooked up a reusable method to the Loaded and Submitted events of my DomainContext. The idea is to take the events’ EventArgs and have a look if they have a UserState property that is the delegate type we are after. Here’s the method:

private void contextEventHandler(EventArgs args)
{
    if (args is LoadedDataEventArgs)
    {
        if (((LoadedDataEventArgs)args).UserState is CompletedDelegate)
        {
            ((CompletedDelegate)((LoadedDataEventArgs)args).UserState).Invoke(args);
        }
    }
    else if (args is SubmittedChangesEventArgs)
    {
        if (((SubmittedChangesEventArgs)args).UserState is CompletedDelegate)
        {
            ((CompletedDelegate)((SubmittedChangesEventArgs)args).UserState).Invoke(args);
        }
    }
}

And here’s the constructor of the presenter where I hooked up the method and handled events generated by the view:

public HomePagePresenter(HomePage view)
{
    this.view = view;

    catCtxt = new CategoryDomainContext();
    catCtxt.Loaded += (s, e) => contextEventHandler(e);
    catCtxt.Submitted += (s, e) => contextEventHandler(e);

    view.Click += (s, e) =>
        {
            if ((s as Button).Tag.ToString() == "Save")
            {
                catCtxt.SubmitChanges(new CompletedDelegate(dataSubmitted));
            }
            else if ((s as Button).Tag.ToString() == "Reject")
            {
                catCtxt.RejectChanges();
            }
        };

    loadData();
}

The key part of the above is catCtxt.SubmitChanges(new CompletedDelegate(dataSubmitted)); which sets the UserState as the delegate. Now, when the call to submit completes, the method dataSubmitted will be called. Here is that method:

private void dataSubmitted(EventArgs e)
{
    SubmittedChangesEventArgs args = e as SubmittedChangesEventArgs;
    if (args.Error != null)
    {
        HtmlPage.Window.Alert(args.Error.Message);
    }
    else
    {
        HtmlPage.Window.Alert("Data submission complete");
    }
}

Finally, it’s worth taking a look at the loadData() method which again passes in a delegate as UserState:

private void loadData()
{
    catCtxt.LoadCategories(null, new CompletedDelegate(dataLoaded));
}

And the dataLoaded method:

private void dataLoaded(EventArgs e)
{
    notifyChange("Categories");
}

And to road off the code bits, here’s the simplistic DomainService class I used in the example:

[EnableClientAccess()]
public class CategoryDomainService : DomainService
{
    public IQueryable<Category> GetCategories()
    {
        return CategoryHelper.GetCategories().AsQueryable();
    }

    public void InsertCategory(Category cat)
    {
    }

    public void UpdateCategory(Category newCat, Category originalCat)
    {
    }

    public void DeleteCategory(Category cat)
    {
    }
}

All in all I was pretty happy with this technique. It seemed to make ria services a little more WCF-like to me, while still retaining all the major benefits of ria services. The code is still pretty rough, but hey – all my test cases are now passing and the code is a lot more readable than it was. Happy days!

NOTE: It’s probably worth pointing out that the July CTP of ria services may well render this example obsolete when it comes out. soon i hope!!!

 

Get the source

Categories: Work

Comments

software development services
software development services United States on 11/21/2009 6:57:20 PM

I am also a software developer... but I am only a beginner now. I have just started to work with .NET RIA services. I have to admit that this sphere is really difficult for me. Reading your post I have found many useful advices about it. Thanks a lot for the great article man.

payday loans
payday loans United States on 12/20/2009 7:31:11 PM

Hmmm interesting stuff

DVD to 3gp converter
DVD to 3gp converter United States on 12/22/2009 11:11:46 PM

Oh my god! I'll never understand these programming language!!

Hirephpdevelopers
Hirephpdevelopers United States on 12/29/2009 7:40:40 PM

Here given details about the .Net queries.Nice functions details are given here.

no credit check payday loans
no credit check payday loans United States on 1/20/2010 2:42:10 AM

The more we give of anything, the more we shall get back.

Loans in TN
Loans in TN United States on 1/21/2010 1:31:09 PM

Believe in yourself, never give up and go about your business with passion drive and enthusiasm.

web based crm software
web based crm software United States on 1/22/2010 12:08:44 AM

CRM methodologies are focused on building individual customer relationships for the purpose of creating and maintain a loyal customer base.

pay day loans
pay day loans United States on 1/23/2010 12:21:28 PM

Those who stand for nothing fall for anything.

va streamline refinance
va streamline refinance United States on 1/27/2010 8:13:39 PM

Don’t stop blogging! It’s nice to read a sane commentary for once

business opportunity
business opportunity United Kingdom on 1/29/2010 9:20:35 AM

Thanks heaps to the author!

34DVD
34DVD United States on 1/29/2010 4:06:59 PM

Your scenario has me puzzled. I'm persuaded the problem is in how the control responds to a disconnect between the visual state (showing bad value) and the object state (retaining a good value). If SL implemented IDataErrorInfo (or equivalent) this could be managed without calling setters. Even as it is today it could be so: the control could compare the result of calling getters with what appears in the control (making use of the converters of course); tricky to be sure ... but better than calling setters.

instant payday loans
instant payday loans United States on 1/30/2010 3:55:34 AM

Where much is expected from an individual, he may rise to the level of events and make the dream come true.

faxless payday loans
faxless payday loans United States on 2/5/2010 9:21:32 PM

Make a better friend of every man with whom you come in contact

acai berry review
acai berry review United States on 2/15/2010 11:49:32 PM

Vision is the art of seeing things invisible to others.

buy marketing lists
buy marketing lists United States on 2/24/2010 6:57:22 AM

Well, in any kind of business or blog site, you need to be aware that you must advertise this to be popular. Hopefully this will be a big help.

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading