I've been working with Petar Kozul and somewhat with fellow Magenic employees Kevin Ford and Shawn Wildermuth on some new enhancements to the framework.
My primary focus in this version is to support localization.
If you are willing to help translate the CSLA.Resources text into your local language please let me know – it would be nice to have major languages supported in the download!
Rule Manage Fixes
I also fixed some issues around the Rules Manager, ensuring that rules are re-added to the list in various scenarios around CancelEdit and so forth. This also involved making sure that the ISerializationNotification interface was called properly when serializing and deserializing entire object graphs (since child objects weren’t being handled properly in all cases).
Exception handling and call stack data
I also addressed some issues around returning exception data and the call stack from a remote DataPortal server back to the client. This is a tremendous benefit for debugging and it is probably worth upgrading to 1.5 for this change alone.
The easy part of localization was to change all output text to come from a resource assembly. Other than only having English in the assembly, that was easily done.
Anyone wanting to contribute translations is most welcome!!! You can go here to see a list of the existing resource files, and if you have another language to contribute please feel free to email me. Thank you!!
The hard part is transferring the client-side culture information to the server. Sure, I could have hacked something, but I wanted to do a decent job of it like Petar has done. As we got talking, it became clear that I could make Petar's life a lot easier in several ways by providing a more general solution.
So, the changes got interesting.
- CSLA.Resources now contains the literal text values for any output text (mostly exceptions) from the framework.
- There is now an ApplicationContext class that has ClientContext and GlobalContext properties
- ApplicationContext.ClientContext is a HybridCollection that is automatically transferred from the client to server (if the server-side DataPortal is remote). You can put anything in here you need to send from client to server on every DataPortal call - for instance, the client's culture info. If you don't use this feature, nothing is transferred.
- ApplicationContext.GlobalContext is a HybridCollection that is automatically transferred to and from the client and server (if the server-side DataPortal is remote). You can put anything in here you need to have available and changable on both client and server. If you don't use this feature, nothing is transferred.
- The client-side DataPortal now raises two Shared events. OnDataPortalInvoke is raised before invoking the server-side DataPortal, and OnDataPortalInvokeComplete is raised after the server-side DataPortal call is complete.
- The server-side DataPortal now calls two new DataPortal_xyz methods. DataPortal_OnDataPortalInvoke is called before the "real" DataPortal_xyz method is invoked, and DataPortal_OnDataPortalInvokeComplete is called after the "real" DataPortal_xyz method is invoked.
- To support the server-side change, all business base classes provide default (empty) overridable implementstions of the new DataPortal_xyz methods.
- Breaking change! To support the command object concept, there's now a CommandBase class from which your Command objects can inherit. If you don't inherit from this base class, or manually implement the two new DataPortal_xyz methods then the DataPortal will fail when interacting with your objects.
- Breaking change! The DataPortal now throws a DataPortalException for any exceptions that happen during DataPortal access (including exceptions thrown in your DataPortal_xyz methods). This new exception brings the GlobalContext back to the client even if an exception occurs. It also brings back the business object in whatever state it was in when the exception occured - and you can get that object reference from the DataPortalException object if you need it. Finally, this exception now includes the full StackTrace information from the server, so you can now gain visibility into where the exception occured in your DataPortal_xyz method, which is a big benefit for debugging!
This will likely be the last major change to CSLA .NET for version 1.x of .NET. I expect to primarily focus my energies on .NET 2.0 and thus CSLA .NET 2.0 after this is complete.
Petar is helping me with final testing of the enhancements listed here. Look for a beta of 1.5 in VB soon. Once I'm satisfied that the changes are reasonable I'll port them to the C# version as well.
Any comments or thoughts on these features are welcome. I think that the changes open up a lot of potential customization, since they allow you to plug into key points in the DataPortal mechanism. Certainly they are simplifying some of the really cool stuff Petar has done in ActiveTracker.