Skip navigation

Managing State in CAB Smart Clients

Some time ago I posted about the interesting features of CAB State. I asserted that it was a useful way to compose and maintain client state and express your model (as in the Model-View-Presenter trinity). I changed my mind about this some time ago, and, no, I’m not feeling architectural guilt1.

Moving right along…

The State Bag Stuff in CAB is Evil

WorkItem.State, Presenter<T>.State… that’s what I’m talking about here. That and the StateChanged attribute. These are features that seem convenient on the surface; a consistent means of keeping and tracking state in your smart clients. Finally a solution to all of our smart client state management problems.

No. No, no, no… It is evil. Evil I tell you!

If you’re relying on the state dictionary you’re essentially giving back the benefit of strong typing. You’ve just lost the benefit of strong typing as soon as you throw something into a name-value collection (dictionary). You’re constantly casting objects you throw into the state back leading to ugly and convoluted code.

State in CAB is confusing. You expect it to dependency inject down the WorkItem tree, but it doesn’t. There are also some questionable WorkItem-lifecycle related things with the StateChanged attribute. Namely, it doesn’t fire predictably when you’re looking to add everything to a WorkItem you need to and just run.

The use of the State features encourages bad WorkItem programming. Keep in mind that the WorkItem is only a “container” (dependency injection container). Once state gets involved you’ll find your WorkItem Controller (we’re all using these, right?!) growing in size and scope. I want the Controller to be as lean-and-mean as possible. I want it to focus solely on setting up the scenario, adding my views/services/whatnot to the DI container, and handling events for orchestrating messages between views (in a multi-view/composite-view WorkItem scenario). That’s it… the single responsibility principle for WorkItems.

The Power of Explicit Intention Compels You

My proposal is simple: factor state management responsibilities into the appropriate CAB assets. WorkItems, Views, Presenters, and Services serve specific roles in CAB. Why not give each a specific, cooperative responsibility in the state management lifecycle? Let’s take a look and break it down…

(Click the image for a clearer copy of this sequence diagram)

1. The client code first creates a Startup Object and then sets up a ControlledWorkItem<T>. It calls the overloaded Run method of the WorkItem’s controller class and feeds the StartupObject in as a parameter.

2. Inside the Run method overload of your ControlledWorkItem<T> create a View that takes the same Startup Object in its constructor. This View will implement an interface that defines a get property that allows the Presenter to access the Startup Object. Add this view to the WorkItem’s SmartPart collection. (Note: if you prefer you could implement a setter or method in the Presenter to shove the StartupObject in from the View).

3. The View will build up the presenter via ObjectBuilder and the [CreateNew] attribute. After the View is loaded, the Presenter will obtain references to various additional services that gather additional state using the values in the Startup Object to call methods on CAB Services.

4. The presenter gets the “Starter Object” from the View (remember, originally passed in by the WorkItem Controller) and call into services to get additional required state. If you have a composite view (a view containing other views) have them do the same thing: presenter gets data from service(s), shoves said data into view(s)…

5. The CAB service is the gateway, facade, or layer supertype that allows access to the state owned by whatever lives under those services: Web Services, legacy systems, databases, domain models, etc. Put your Enterprise Library caching and entity mapping or transformation code in these services along with any features toward making getting at the state more performant and/or reliable. You may want to publish events with the CAB Event Broker in these services that indicate that the state has changed. As far as EventPublication scope goes, remember that it’s totally fine to have services that live at a certain level in your WorkItem hierarchy. Also these kind of events will (typically) be okay to go global with; you’ll want to notify everybody. Consider using an EventArgs<T> to pass enough information to determine if the event applies to the situation.

Missing Pieces

Clearly this approach isn’t an automated end-to-end state management framework (beware of things calling themselves that, IMHO). It’s more of a practice for managing state that requires application by an individual developer. One of the thing the state features of CAB promise is the ability to dehydrate and rehydrate your workitems. So you can call something like WorkItem.Save() and the state bag will persist to a configured location.

If you dig a little into CAB, you’ll notice that this functionality is implemented as a CAB service. I’d recommend that you, sure, take a look at that, but implement your own CAB service (a “foundational service”) if you really need to save state on the client between application instances. Of course you should question that need relentlessly. It is a cool feature, but how many smart clients really need it? (Yes, I know that it is a legitimate need at times). If you require this is it because you’re going offline? If not, I’d suggest you implement draft storage and resume logic in the server layers of your application and database.

You have to remember that CAB is a different beast than the Smart Client Offline Application Block or the User Interface Application Block. It addresses the need to create composite, plug-in style UIs. Therein lies it’s strengths… so, let’s use the good parts; there are certainly lots of those!

—-

1 Architectural guilt: only feel it when being self-indulgent in your design. In any case, move on quickly. Consider Emerson’s classic quote, “a foolish consistency is the hobgoblin of little minds.” Anyway, architectural guilt, another post for a rainy day…

[tags].NET, Smart Clients, SCSF, CAB, State Management[/tags]

One Comment

  1. Posted September 6, 2007 at 5:09 pm | Permalink

    http://free-sex-lolita-tgp.com/lolita-zoo-tgp.html lolita zoo tgp

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*