Bank Teller quickstart: Why state stuff is replaced by a service?

Jul 11, 2007 at 7:18 PM
Hello,

I have a question regarding Bank Teller quickstart's design you guys migrated to SCSF v2. Why did you replace CAB's state usage to a context service? Were there any thoughts about state's disadvantages?

-
Thanks,
Leonid
Coordinator
Jul 12, 2007 at 2:16 PM
Is there any real advantage of the WorkItem State? I like to have control over the state of my app and don't want to couple my code to the WorkItem state. Using a context service is a cleaner approach in my opinion and it allows me to push it in any context and use events for context propagation, etc.
For instance, when you need to migrate the app to Acropolis for instance you may find easier to migrate a service than if code that uses the State.

Matias
http://staff.southworks.net/blogs/matiaswoloski
Developer
Jul 11, 2008 at 6:28 AM
Edited Jul 12, 2008 at 2:38 AM
The question was "Were there any thoughts about [WorkItemState] disadvantages".
And the response asks "is there any real advantage?"

I'd like to extend this discussion and explore whether WorkItemState is "completely useless".

It may be the case, and I'd be interested in other opinions.
Does it needlessly couple your code? Make it harder to test? Is there always a better way to achieve the same functionality?
Developer
Jul 12, 2008 at 6:11 PM


PandaWood wrote:
The question was "Were there any thoughts about [WorkItemState] disadvantages".
And the response asks "is there any real advantage?"

I'd like to extend this discussion and explore whether WorkItemState is "completely useless".

It may be the case, and I'd be interested in other opinions.
Does it needlessly couple your code? Make it harder to test? Is there always a better way to achieve the same functionality?


I'd like to extend this discussion and explore whether WorkItemState is "completely useless".

Basically, IMO, yes. When I was at Patterns and Practices conference a couple years ago, I was able to listen in on a hallway conversation with Brad Wilson where it revealed that the State bag was one of the things they actually wanted to take out of the CAB, but they didn't have the time to do it. The impression I got from Brad was that he thought the State bag was a mistake, and that state management should have not been done by the CAB, or should have been done differently, in a way that gave developers more control.

As to the last three questions you asked, my answers are: yes, yes and yes.

I find the State bag to be wholly inadequate for state management. It is basically little more than a hash, with an event on it. Where I work, we wrote our own state management service. It gave us a lot more control over how the state of an object was stored, persisted (if we choose), restored, etc. It also allowed us to create an interface with methods that were strongly typed, and it was dead-simple to use in a unit-testing scenario (no reliance on a TestableRootWorkItem, for instance). I like my classes (Presenters, etc.) to be dependent on other classes with public-facing interfaces that I can inject via dependency injection and mock with a tool like RhinoMocks. I do not like being dependent on anything in the CAB, especially a stub of a heavyweight object like WorkItem, which was not built for testing (no virtual methods, not enough usage of interfaces, etc.)

CAB was a neat idea, but it was poorly implemented from a testing standpoint. Try and mock something in CAB and you'll run into problems because of the aforementioned limitations. Now take a look at what Scott Guthrie's team is doing with the MVC framework and see the difference: pluggable IoC container, heavy use of interfaces, virtual methods by default. I'm glad some lessons were learned from CAB and that some knowledgeable people's opinions in the .NET world were listened to for the ASP.NET MVC framework, but for CAB  it is too late.

These problems with CAB can be overcome, however. A lot of things can be wrapped behind custom interfaces allowing you to exploit a much better system.

The way we write all of our code is: we make as few direct references to the CAB framework as possible. The exception (as of right now) is Workspace.Show(), and only because I haven't abstracted that away yet. Everything else that relates to the CAB, for us, is either (a) wrapped up in a subclassed WorkItem that we utilize, or (b) hidden behind interfaces that are easy to mock (for instance, all calls to WorkItem.Items, or WorkItem.SmartParts, or WorkItem.WorkItems are abstracted away behind an IContainer interface (ours) that has methods like IContainer.AddNew()).

Anyway, I've rambled. I think the State bag is a waste of time and I prefer to see a service handle that. The way I approach solutions like this is: what if I wasn't using the CAB? How would I solve this problem in a way that was (a) easy to test and (b) was clean and simple to use with minimal development pain? A service works whether the application is a CAB application or not. The State bag is proprietary... A word that is wholly evil all by itself.


Developer
Jul 13, 2008 at 2:38 AM
Edited Jul 13, 2008 at 2:39 AM
<<Anyway, I've rambled...>>
Not at all, much appreciated. A ramble is good in this sort of discussion.
I'm going to reassess where I've used WorkItemState. I didn't use it much, but I know it made things hard to test in cases where I also used the StateChanged event.