Any Suggestions for this particular problem

Topics: CAB & Smart Client Software Factory
Dec 28, 2006 at 5:28 PM
originally posted by: Siraris

I'm trying to figure out the best way to manage what I'm currently working with across all modules/views/worksitems/etc. Meaning, let's say I have 10 different workitems I am working with and I want to know what the current customer I am working with is. I could also use the class to keep track of the current window I'm on, etc, but let's just stay with the Customer idea. Is there anything that SCSF has already, or any suggestions or solutions that other people have come up with that would work here?

To reitterate, just a way so that I can know what customer I am currently working with across multiple workitems without having to pass it between every single workitem I do.

Thanks in advance.
Dec 29, 2006 at 10:59 AM
originally posted by: MarcoPaul

How about create a service, for example, CurrentContext, that contains the active workitem (use case).
Dec 29, 2006 at 1:11 PM
originally posted by: bil_simser

You could use RootWorkItem.State"CurrentCustomer" and assign the object to it.
Dec 29, 2006 at 1:53 PM
originally posted by: MarcoPaul

I do not believe that will work correctly when dealing with child workitems.
Dec 29, 2006 at 2:11 PM
originally posted by: bil_simser

Why not? He can always get the RootWorkItem (there's only one) from any child and get the customer information from it. All children are childs of the root work item created by the shell. What's the problem?
Dec 29, 2006 at 10:17 PM
originally posted by: Siraris

I appreciate the responses. I actually thought of something yesterday and implemented it and it worked just fine. I made a static property in my class, so all I have to do is include the namespace it's in, and do MyClass.CurrentObject.whateverIneed. Kind of similar to what bil_simser suggested.

Just curious, but would .State accept the object that I wanted and keep it in scope across different modules? I guess it would since it's all stemming from rootworkitem which is spawned from the shell, correct?
Dec 30, 2006 at 5:19 AM
originally posted by: MarcoPaul

Well, state has to be copied to child workitems, thus if a reference changes down in the chain, it will not be propogated up to it's parent workitem.

    • edit **
Sorry, I didn't notice your code snippet was referring to the rootwork item.
Dec 30, 2006 at 7:07 AM
originally posted by: bil_simser

Right, there is only one root workitem. Essentially it's a global variable like what you implemented. Someone might say sticking it in RootWorkItem is just a hack, but I think if you really want to pass a business entity around, it's the easiest way to do it and not worry about it. As an aside, I would look at something less icky than "global" variables like using publish and subscribe just because using something like RootWorkItem is easy but it's hard to tell what state that entity might be in (will it always be valid, do you update it, etc.). Using pub/sub you just pass the right entity around to subscribers through the event argument.
Dec 30, 2006 at 7:17 AM
originally posted by: MarcoPaul

Good point.

In my applications, I use a Context service that contains things much like the HTTPContext object used in web applications. For example, whenever the Context.CurrentProject property is changed, I publish an event for all observers to handle. The only time I really use the state bag is when i have a list/edit screen. i pass entities via the state bag.
Dec 30, 2006 at 4:10 PM
originally posted by: Siraris

OK, perhaps this will kill two birds with one stone (Marco, Bil I hope you guys can come to my rescue!)

I did some more research into what you both said, and I think that using this State will work perfectly. I also may combine it with events, so that I can automatically refresh the windows I want to work with. But let me talk about some of the things i'm confused about.

In the BankTeller quickstart they touch on what I want to do, by creating this StateConstants class. They then assign the curent customer by saying: workItem.StateStateConstants.CUSTOMER = customer; That's fantastic, and I can do that when the user finds a customer. The problem is, and this stems from my lack of understanding of working with WorkItems, but how do you access that WorkItem across numerous different views/classes/workspaces in a module?

So, let's say I have the view where I'm doing a search for the customer, I then double click the customer in a listview, assign the customer found as the current customer I'm working with (workItem.StateStateConstants.CUSTOMER = customer;), and open up a view where I manage the customer (in the same workspace). How do I access that workItem if I want to say "OK, give me all the information about that customer so I can work with it in this view, and then when I'm done with this view (if I've made changes) I want to update that customer I'm working with". Then I open another view to work with that customer involving other data, but needing that base overall customers information for what I am doing, how do I then still work with that same item? If I just do WorkItem.StateStateConstants.CUSTOMER is that going to give me the current customer that I am working with? Do I need to pass a workitem around everywhere I want to use it, or will it just be available throughout the project? If I just do WorkItem. (calling the workitem class) and invoke the state, will that always have the customer I want to work with?

Sorry for such a big block of text, but I just have all these thoughts and ideas swirling in my head and I'm starting to fizzle out :).

So this is the big thing for me; understanding how I go through all the views and whatnot that I want to work with, and continue to work with that same customer until I either find a new customer to work with, or close the program. I want to be able to open and close views in the workspace as well, and continue to work with that same customer. To use an analogy, if I check into a hospital, I have my overall self (height, weight, blood type, SSN, whatever) and I can move freely throughout the hospital to radiology, or surgery or blood testing, whatever it is, and all those departments can say "OK, what is Andrew's blood type" or "What is Andrew's height" or "What is Andrew allergic to".

I really hope someone can help out here. I think I'm really close to getting this, but it's just not clicking. I have the overall concept down in my head, but being able to implement it in code is where the problem is.
Dec 30, 2006 at 5:13 PM
originally posted by: bil_simser

Siraris,

It's pretty simple (at least in my mind, but then I'm pretty familiar with all this stuff now but that took about 6 months of groking it all). Basically you can consider the root work item a global container. There is only one and the shell creates it. Any other work items in any module all are created a children from it (or grandchildren, great-grandchildren, etc.). You can access the root work item from any module because it's created when the module is initialized.

So the big hurdle I see is just how to implement it and there are a couple of options. It's really up to you but one suggestion might be to create a Customer module (if you don't already have one) and use RootItem.State"CurrentCustomer" to access it. The customer module can create a CustomerLocationService or something to always retrieve it. Then you can just simply make that module one of your core modules that other modules depend on. Through DI you don't need to create the service, just make your presenters set a reference to it through a constructor. That way you can have whatever presenter set or get the current customer in response to needing a reference to it, or like you originally wanted, setting the current customer via the service when one is selected from say a grid or list.

Let me know if you want an example. I can whip up a sample application using a couple of modules that show the basics of how you can reference things, create the service, inject the services into the presenters, etc. I'll probably blog about this now as it does have a few moving parts but if you want a code sample just holler.

P.S. sorry for using "Customer" as an example here, I can't recall at the beginning of this thread what your context was but you should get the idea.
Jan 1, 2007 at 1:39 PM
originally posted by: Siraris

Bil -

A sample application would be FANTASTIC. I am much better at learning from practice as opposed to theory.

I have a module (customer module is fine to call it) and so creating something that allows all other modules to inherent from it would be nice, although only 1 of the other modules would probably use it (I have 4 total modules) but it wouldn't hurt.

My biggest issue is the whole referencing things and accessing workitems, so that would be a huge help. Just curious, but if I wanted to have 4 customers at one time, I could create 4 static names like CurrentCustomer1, 2, 3 and reference them by RootWorkItem.State"CurrentCustomerx", correct?

What is DI btw?

Thanks again bil, where is your blog by the way?

Andrew
Jan 2, 2007 at 6:23 PM
originally posted by: bil_simser

My blog is located at http://weblogs.asp.net/bsimser so you can check out the sample I'll post later there.
Jan 4, 2007 at 3:51 PM
originally posted by: Siraris

Hey Bil - I'm sure you're really busy, but I was wondering if you knew a rough time when you could get the example up in your blog? I'd really appreciate it.