Functionality questions

May 21, 2010 at 11:42 PM

Hi,

I'm considering using these templates for a business object framework at work. I have a couple questions for the author(s) of the templates.

  • Is a "Switchable" CSLA template (an object can be a root or a child) type being considered? It seems that if I set up an entity to use the EditableRootList CSLA type, I can't create New instances of that object. If I select EditableRoot, I can't fetch lists of the objects. Am I missing something?
  • I noticed that the DataPortal_Update method is set up to re-fetch the object from the data source, which I think is too much overhead. From what I can tell, the recommended solution is to detach the entity framework object, and re-attach it upon save (this supports a physically separate data access layer). Would it make sense for the CSLA objects to save the Entity Framework object as a private field, and have calls to properties on the business object just access properties on the Entity Framework object?

    A straightforward implementation requires that saving the object updates all the fields (blowing away any other changes that could have been made. But, it seems that the existing update has this behavior as well (I expected it would only update changed fields if it's going to the trouble of re-fetching the object)).

    It seems that custom tracking could be implemented such that it could update only changed fields even if the data access layer were on a separate server. I'm not completely certain about this, though.

Thanks,

Chris

Coordinator
May 22, 2010 at 4:47 PM
Edited May 22, 2010 at 4:48 PM

Hi. 

First I want to say that this is Beta 1 release, so there are some things missing. We are planning next release and any comment is welcome.

- Switchable is easy to implement and I will put it on the TO-DO list. There are few ways to solve this problem with this Beta version. First is to create Database Views for read-only objects, and use Database Tables for editable Root objects.  That is easy to do, and I recommend this pattern. If this is not acceptable, I was thinking that instead of choosing one CSLA template, we could add property that would be an array of CSLA templates, so you could define as many objects as you want. What do you think about this options?

- DataPortal_Update can be implemented in many ways. For Beta 1 we solved this task using the easiest method, to load entity before update. Many business applications have more inserts than updates, and this is usually not an issue. I was thinking about this, and if there's enough interest, we could solve this problem in a different way, as a generation option.

- If you use Entity Framework, only updated fields are saved to database, so that is probably not a problem. I think there's much other overhead when saving object to a database, so this read-write thing is adding minimum overhead to a save operation.

~Josip

 

Coordinator
May 22, 2010 at 6:23 PM
scriby wrote:
  • Is a "Switchable" CSLA template (an object can be a root or a child) type being considered? It seems that if I set up an entity to use the EditableRootList CSLA type, I can't create New instances of that object. If I select EditableRoot, I can't fetch lists of the objects. Am I missing something?

Root objects are responsible for loading and saving to a database. If you select EditableRootList template, two classes will be generated: List and Single. You can create new and edit existing single objects, but List (root) is responsible for database operations. I recommend you to see code generated with the T4 template.

May 22, 2010 at 8:41 PM

I appreciate the response.

The problem I had with EditableRootList is that the single's New method was marked as internal. It seems that it's intended to only be called from the List class. Is that right? I think CSLA is easier to use if single objects can be saved without going through the list class, but I'm not an expert on the framework.

The performance issue with re-fetching the object before save would be a big deal in my case. I can see small and medium size software solutions not caring so much about the performance impact. I'm expect I'll have to do some customization -- the templates are at least a good starting point.

We have a couple other requirements which I haven't done much research into, but need to figure out. One is instantiating a business object list from the result of a stored procedure call. I think I'll first have to figure out how to load the EF objects from an ad hoc sproc...

I'm also going to need to be able to track changes to individual properties while the business objects live in a separate physical tier. I could see a customization that watches the value of each property (this seems to be complicated if exposing mutable objects), or storing a self tracking EF entity within the CSLA BO. I'm not exactly sure how object graphs will be handled in this case, something else to figure out...

Thanks,

Chris

Coordinator
May 23, 2010 at 12:24 PM
scriby wrote:

I appreciate the response.

The problem I had with EditableRootList is that the single's New method was marked as internal. It seems that it's intended to only be called from the List class. Is that right? I think CSLA is easier to use if single objects can be saved without going through the list class, but I'm not an expert on the framework.

The performance issue with re-fetching the object before save would be a big deal in my case. I can see small and medium size software solutions not caring so much about the performance impact. I'm expect I'll have to do some customization -- the templates are at least a good starting point.

We have a couple other requirements which I haven't done much research into, but need to figure out. One is instantiating a business object list from the result of a stored procedure call. I think I'll first have to figure out how to load the EF objects from an ad hoc sproc...

I'm also going to need to be able to track changes to individual properties while the business objects live in a separate physical tier. I could see a customization that watches the value of each property (this seems to be complicated if exposing mutable objects), or storing a self tracking EF entity within the CSLA BO. I'm not exactly sure how object graphs will be handled in this case, something else to figure out...

Thanks,

Chris

EditableRootList is the template for situation when you have a list of items that needs to load and save self to a database. When using this pattern, list is root and list items are child objects, and usually items are created by list (overriding AddNewCore base method). Another possible pattern is the one you mentioned, when you have a list, and independent writable item. In that case I suggest you creating two independent objects, one for read-only list (ReadOnlyRootList) and another for editable objects (EditableRoot). Take a look at the Demo project,  there you have list of orders as a read-only list, and another editable object Order, that is used for editing.

I agree about reloading having impact on performance, but for many uses that overhead is minimal. As I said, we can implement this in many ways, this is an open source project and we are open for suggestions.

Change tracking is part of CSLA framework, and has not much to do with code generation. CSLA objects and graphs are serializable, and can be used effectively in multi-tier scenarios. Take a look at the FieldManager CSLA class. For details and questions about CSLA framework good starting place is Rocky's forum: http://forums.lhotka.net/

Cheers,

Josip

Jun 23, 2010 at 7:45 PM
jbudimir wrote:

Hi. 

First I want to say that this is Beta 1 release, so there are some things missing. We are planning next release and any comment is welcome.

- Switchable is easy to implement and I will put it on the TO-DO list. There are few ways to solve this problem with this Beta version. First is to create Database Views for read-only objects, and use Database Tables for editable Root objects.  That is easy to do, and I recommend this pattern. If this is not acceptable, I was thinking that instead of choosing one CSLA template, we could add property that would be an array of CSLA templates, so you could define as many objects as you want. What do you think about this options?

~Josip

I like the idea of a Template List so that at least in my Sitatuion a EditableRoot/BusinessBase<> and EditableRootList/BusinessListBase<> can both be created.  I am going to try to hack my way around it for now by modifying the template.

Regardless, your work is giving me a running start and for that many thanks,

Jack

 

Jun 23, 2010 at 8:13 PM
JackMetcalfe wrote:
jbudimir wrote:

Hi. 

 

First I want to say that this is Beta 1 release, so there are some things missing. We are planning next release and any comment is welcome.

 

- Switchable is easy to implement and I will put it on the TO-DO list. There are few ways to solve this problem with this Beta version. First is to create Database Views for read-only objects, and use Database Tables for editable Root objects.  That is easy to do, and I recommend this pattern. If this is not acceptable, I was thinking that instead of choosing one CSLA template, we could add property that would be an array of CSLA templates, so you could define as many objects as you want. What do you think about this options?

 

~Josip

 

 I like the idea of a Template List so that at least in my Sitatuion a EditableRoot/BusinessBase<> and EditableRootList/BusinessListBase<> can both be created.  I am going to try to hack my way around it for now by modifying the template.

 

Regardless, your work is giving me a running start and for that many thanks,

 

Jack

 I want to correct myself:

 

When EditableRootList is selected both a BusinessBase<> and BusinessListBase<> class are created, which seems like a reasonable option.  The template list could prevent the generation of unused code but that is a lower priority issue.

 

My problem really is that when EditableRootList/BusinessListBase<> classes are generated the referencing entities encounter a problem.

 

 

 Specifically in the the ReadData() method of the Data Access Layer their is a problem with the loading of navigation properites that are referencing a collection.  A line like:

 

 LoadProperty<TenantList>(TenantsProperty, TenantList.Get(data.Tenants))

 

 is created in the class referencing the EditableRootList/BusinessListBase<> but no TenantList.Get() method is created that accepts a EntityCollection<Tenant> so errors are encountered at compile time.

 

In this case it seems like we would the Get method in the TenantList class that accepts the EntityCollection<Tenant> argument.  This new method in the TenantList class seems like it should be implemented as an Internal method using a child data portal fetch.  This Entity Framework 4 dependencies are not leaked to CSLA business object callers and a potential cross process, or even machine, boundary and the associated marshalling are not encountered.

 

Coordinator
Jun 23, 2010 at 11:45 PM
Edited Jun 23, 2010 at 11:47 PM
Tomorrow I'll answer in more detail. Here's a quick answer: If I get this right, you have a root object X and TenantList as a public property of that object. In that case you should select EditableChildList template for Tenants and Get() method will be generated. Regards, Josip
Jun 24, 2010 at 2:36 AM
jbudimir wrote:
Tomorrow I'll answer in more detail. Here's a quick answer: If I get this right, you have a root object X and TenantList as a public property of that object. In that case you should select EditableChildList template for Tenants and Get() method will be generated. Regards, Josip

When I do what you suggest it does get rid of the issue I described.  Perhaps if I describe the scenario I am trying to support you can guide me in the direction T4CSLA is being designed to support.

Given a lease that has one or more owners of the property being leased how would you expect the creation of a new lease and those owners to be performed in the calling code?

Lease is created with a Csla Class Template of EditableRoot and LeaseOwner with EditableChildList

One approach, but certainly not the only possible approach, is:

Lease lease = Lease.New();
lease.BeginEdit();

... Set lease properties

LeaseOwnerList leaseOwnerList = lease.LeaseOwners;

LeaseOwner firstOwner = leaseOwnerList.AddNew();  // Since T4CLSA generated code does not create an Owners collection ie.) OwnerList ownerList would be null and an error thrown here

... Set firstOwner properties

lease.ApplyEdit();

lease.Save();

Another possible approach is:

Lease lease = Lease.New();
lease.BeginEdit();

... Set lease properties

LeaseOwnerList leaseOwnerList = LeaseOwnerList.New();  // Since T4CSLA marks this as internal it would not be accessible across assemblies

LeaseOwner firstOwner = leaseOwnerList.AddNew();

... Set firstOwner properties

lease.LeaseOwners = leaseOwnerList;

lease.ApplyEdit();

lease.Save();

What client calling semantics is T4CSLA expecting in situations such as this?

Thanks again for your help,

Jack

Coordinator
Jun 24, 2010 at 1:25 PM
Edited Jun 24, 2010 at 1:27 PM

1. Lease is root object (EditableRoot) responsible for starting and commiting db transactions and calling child objects CRUD methods

2. LeaseOwner is child object, and LeaseOwnerList is a child list. Both objects are created if you select EditableChildList template

Generated classes are partial, so you can extend them by implementing existing partial methods, by implementing new methods or properties, or by overriding base class methods. If you've seen the DemoProject, I've added few partial classes in BLL just as an example of what can be done.

Every class should be responsible for it's own behaviour and data. Following that simple rule your business model would look like this:

- Lease has a property LeaseOwners (typeof LeaseOwnerList)

- Add new partial class Lease in BL (must have the same namespace as the generated class) and implement partial method Lease.AfterCreate. This is where I would create new LeaseOwners list, so after Lease is created, LeaseOwners are created also. (check Orders and OrderDetails classes in DemoProject)

- Add new partial class LeaseOwnersList and override AddNewCore base CSLA method. This is where you should create new LeaseOwner

- Add new partial class LeaseOwner and implement partial method AfterCreate() to populate fields

 

Calling code should look like this:

Lease lease = Lease.New(); //we implemented AfterCreate partial method to populate default fields

LeaseOwner owner = lease.LeaseOwners.AddNew(); //we overrided AddNewCore to create new Owner by factory method LeaseOwner.New()

//optionally populate additional fields

lease.Save();

Was this helpfull at all?

~Josip

Jun 24, 2010 at 3:15 PM

Yes, that helps.  I will proceed as you describe.

Using your work as a learning vehicle I should be able to create another T4 Template that uses the EDMX file for information to generate extensions to the classes that are being created by T4CSLA.

This way I can continue to benefit from revisions to T4CSLA without the retrofitting required if I were to modify the T4CSLA template.

Does that seem like a reasonable solution?

Thanks for your patience and help,

Jack