I am designing a LightSwitch 2012 application to manage requests, and I want to be able to update the request state with the same reusable code across all of my screens. For example, A user can change a request state in the approval screen, the fulfillment screen, etc. Which are called by a button. Currently, I have a method in each of the .cs files where I need to update the request, using the partial void <ScreenCommand>_Execute()
methods. I am trying to change this so I can update the code from one place instead of everywhere, and I also want to not have to copy the methods to new screens that I add a button to.
Now normally I would put this in Application.cs or somewhere else with global access, but I don't have access to the same DataWorkspace
object. I also pass in the this.DataWorkspace
object from the screen, which allows access to the SaveChanges()
method. However, this seems a little smelly. Is there a better way to deal with this or a better place to put reusable commands that you want to be able to assign to buttons on multiple screens? Currently I have to be really careful about saving dirty data and I still have to wire everything up manually. I also don't know if the code runs in the proper context if it's in the Application.cs file.
To clarify, yes, I do want this to run client side, so I can trigger emails from their outlook inboxes and the like.
What you're trying to do is simply good programming practice, putting code that's required in more than one place in a location where it can be called from each of those places, yet maintained in just one place. It's just a matter of getting used to the way you have to do things in LightSwitch.
You can add code in a module (or a static class in C#) in the UserCode folder of the Client project. That's part of the reason the folder exists, as a place to put "user code". To do this, switch to File View, then right-click the UserCode folder to add your module/class. Add your method in the newly created module/class. You can create as many of these as you like (if you like to keep code separated), or you can add other methods to the same module/class, it's up to you.
However, I wouldn't go passing the data workspace as a parameter to the reusable method that you create. I wouldn't even pass the entity object either, just the values that you need to calculate the required state. But the actual invoking of the data workspace's SaveChanges method should remain in the screen's code. Think of the screen as a "unit of work".
In each button's Execute method (in your various screens), you call your method with values from the entity being manipulated in the screen & return the result. Assign the calculated returned value to the entity's State property (if that's what you have), then call the screen's Save method (or use the screen's Close method, passing true for the SaveChanges parameter). There's no need to call the data workspace's SaveChanges method, & you're doing things the "LightSwitch way" by doing it this way.
Another benefit of doing it this way, is that your code can now be unit tested, as it's no longer dependent on any entity.
I hope that all makes sense to you.