BusinessBase derived class loses IsDirty and Save capability when exported from class library

BusinessBase derived class loses IsDirty and Save capability when exported from class library

Old forum URL: forums.lhotka.net/forums/t/6443.aspx


Neo posted on Tuesday, February 17, 2009

Hello, I am using CodeSmith to generate a class that derives from the CSLA BusinessBase type to read and write to an SQL database.  The derived class overrides Save() and calls base.Save().  When called after data has been changed, this normally results in DataPortal_Update() being called which, again, is overridden in the derived class.

However, I have created a class library that exposes itself as a Windows Service.  I have a client GUI (an XBAP) that has a Web Reference to this class library.  One of the methods on my class library returns the type that is derived from BusinessBase.  This is automatically exported to the client application as a type with exactly the same name but is actually a wrapper of the original type.  This isn't apparent until I see that all the properties have been prefixed with an underscore.

However, when I make changes to this wrapper object in the client application and pass it back to the class library via a parameter to a public method (whether by reference or by value), it seems that the data is copied over, but the IsDirty flag is set to 'false'.  In fact, the wrapper class doesn't set its own IsDirty flag to 'true' in the client application when any of the properties change, it's like the IsDirty flag is completely redundant in the exported wrapper class.

This presents a problem because I am unable to use the exported objects to change data and save it.  The only way round this is to instantiate another object of the original type inside the class library method (which means getting the record from the database again) and copy the data from the passed object into it manually.  Or, reference the CSLA libraries in my client application and remove the need for exporting the generated classes from a Windows Service class library.  But this means I'll no longer have a service runnable on a server that can be reused by other client applications.

It seems to me that the IsDirty flag should be updated in the wrapper class just as it is in the original class that derives from BusinessBase.  Is a fix planned for this, or am I missing something, or is there another suitable method for achieving my aim or working around this particular problem?

Many thanks,

Jason

ajj3085 replied on Tuesday, February 17, 2009

It sounds like you're directly exposing your BOs in the web service.  This isn't supported.  If that is what you're doing, you'll have to consider writing DTOs which are exposed by the web service. 

tmg4340 replied on Tuesday, February 17, 2009

What you're seeing is a by-product of the service.  The object that is returned to you via your Windows service is not the same as what's in your actual class library.  It is the serializable form of your object.  The thing about serialization is that the code in your class (or the CSLA base classes) doesn't come along for the ride - only the data.  All the BO properties (like IsDirty) that the CSLA class manages for you are handled via the CSLA code.  So you aren't getting the behavior you want.

What you should do is read the chapters in Rocky's book surrounding web and WCF services.  The fact that you've chosen to expose your objects via a Windows service doesn't solve the "service boundary" issues inherent in web and WCF services.  It just changes how you access the service.

Ultimately, if you're using the Windows service as a kind of middle tier, then the only way to get what you want is to have a copy of your BO class library present on the client.  If you intend to simply expose your BO's as a service for your XBAP application to consume, then you have to follow the service rules outlined in the service chapters in Rocky's book that I mentioned above - and live with the consequences of that approach.

HTH

- Scott

Neo replied on Thursday, February 19, 2009

Thanks for your replies.  I assume a DTO is essentially a wrapper class for the CSLA class.  In which case, our SOAP-compatible class that derives from BusinessBase could be the "DTO", yes?

Anyway, I have managed to resolve the issue in a very simple way while retaining the Windows Service as a middle tier.  I've added the following function to the derived class, and the exposed function on the class library simply calls this function on the object passed into it:

        public MyDerivedBusinessClass ForceSave()
        {
            MarkDirty();
            return Save();
        }

JoeFallon1 replied on Thursday, February 19, 2009

Neo:

I assume a DTO is essentially a wrapper class for the CSLA class. 

Bad assumption.

CSLA BO's are not designed to be service objects. You really need to read the book which has a whole chapter on this topic.

Bottom line - a DTO is a simple class that only contains the raw data, some Public Properties and no methods.

Joe

 

Copyright (c) Marimer LLC