Async business methods in Silverlight

Async business methods in Silverlight

Old forum URL: forums.lhotka.net/forums/t/5588.aspx


dnwheeler posted on Tuesday, October 14, 2008

I'm in the process of learning to use CSLA 3.6 with Silverlight (not having used any previous versions) and am struggling a bit due to the many disparate pieces of documentation scattered around. As such, I need some advice and guidance.

Here's my basic scenario (reduced to the relavant bits): I have two data objects (User and Group) in a many-to-many relationship (GroupUser table is used to link the two).

On the business side, I have a User object containing a GroupList object containing GroupInfo objects. Likewise, there is a Group object with a UserList object containing UserInfo objects.

I am not having any problem with with basics of fetching and displaying existing data, or creating new Groups and Users. The challenge is how best to add new "joins."

Currently, at the point I need to do the join, I have a User object and a Workspace object on the client (I do *not* have a UserInfo or WorkspaceInfo object).

It seems like the obvious choice would be an "AddUser(int userId)" method on the GroupList object and a corresponding "AddGroup(int groupId)" to the UserList object - each would do the same thing. The trick here is that these methods would have to be executed asynchronously (can arbitrary DataPort_xxx methods be called within a BO?).

Another option is to create a new BO that corresponds to the "join" table, although this results in the business logic being designed around the requirements of the relational data.

Any thoughts or suggestions on how best to approach this? Is there a different organization for my business logic that makes more sense? Would I be better off eliminating the xxxInfo objects and using lazy-loaded xxx objects?

--Doug

RockfordLhotka replied on Tuesday, October 14, 2008

This depends on your desired user experience in some ways.

Do your users expect that adding a relationship (join) will be saved immediately as they do it? Or do they expect that they can do a series of edits (add/remove relationships) and then click Save to commit the changes as a batch?

The second model is far easier on the whole, because you can have your UI work with the business object model to establish the various relationship edits, and then you can just call Save() on the root object to commit all the changes as a batch.

If you do want to establish relationships one-by-one, that's also fine. It requires thinking a little differently however. What you are saying in that case, basically, is that your business object graph is read-only - just representing the data in the database. And you have some "operation" object that is responsible for performing the add-new-relationship operation.

That operation object could be either a Command object or an Editable Root object. Either one will work, though I often find the use of an Editable Root to be simpler (because the user often has to enter other data about the relationship beyond the simple fact that it exists).

Either way, when you save/execute that operation object, it will go to the server and update the database with the new relationship. When that is done, a callback will occur on the client to indicate that the operation is complete. You'll need to write code in that callback handler to update the "read-only" object graph to reflect the changes just made - namely that a relationship has been added/removed/whatever.

In other words, you'll likely have an in-memory set of objects that bind to the UI to display the relevant data. And you'll have a command object that runs to the server to make the requested changes. And you'll have code that responds to completion of the command to update the in-memory set of objects to reflect the change.

dnwheeler replied on Tuesday, October 14, 2008

For the most part, the user does not provide any additional data/parameters (although the client code may do so on their behalf).

Here's a description of the user experience for the initial case I'm trying to handle:

The user is viewing a "home page" that displays a list of groups he is a member of (internally, the page is databound to the User BO, and the group list is bound to the User.GroupList). There is a button to create a new group. When the user clicks the button, a dialog appears where the user can provide the properties for the new group (name, etc.). The new group is then saved.

Internally, the current user needs to be added to the newly created group and as soon as that is complete, the app automatically navigates to a group page (databound to the newly created group). This page includes a list of users that are members of the group (the UserList member of the Group object).

Later, there will be other situations where users can join or leave existing groups. It is unlikely that there will be much need for "batch" operations.

Copyright (c) Marimer LLC