DataPortal_Create vs constructor when using hardcoded default values.

DataPortal_Create vs constructor when using hardcoded default values.

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


mikemir8 posted on Thursday, July 24, 2008

Okay, this might sound as a silly question to many, but I just couldn't find an answer in the forum =).

If I have an editable root object with hardcoded default values, I know a recommended approach is to use the DataPortal_Create method with the RunLocal attribute. But, is there any reason not to put the default values directly in the constructor and have the factory method call the constructor directly? Is it just a convention or are there any design reasons not to do it?

- Miguel

skagen00 replied on Thursday, July 24, 2008

We tend to avoid that practice just so we have a reliable place to have a common area to put certain code such as a call to an abstract method for linking event handlers within the object graph as well as a call to base's DataPortal_Create to check validation rules (Csla.Core.BusinessBase does this).

But if you do use a constructor, you'll just want to make sure you're checking rules for one, which would get bypassed if you avoided DP_Create.

 

Q Johnson replied on Thursday, July 24, 2008

DataPortal_Create is really for those circumstances where you need to load your default values from the database.  Why else go all the way to the server for it?

The constructor should usually be the place to set hard-coded default values. 

The other post's comments about validating may be useful in your context, or not.  It probably depends on the the default values you use and why you use them.

Regards,

skagen00 replied on Thursday, July 24, 2008

I respectfully disagree - [RunLocal()] is there if you don't need your DP_Create to utilize remoting to get to the server. DP_Create is the primary "hook" / dataportal method for which to hydrate new objects.

That said, if the factory method loads a couple properties itself and doesn't use DP_Create, I don't think it's a big deal. He just needs to be sure to check rules, etc, which is handled in Core.BusinessBase.DP_Create

Lalit replied on Friday, July 25, 2008

Hi,

I am quite agree with your point about using DP_Create method but with an exception. I would always prefer to use a constructor instead of DP_Create in case of initialisation with hard-coded values.

Reason is that constructor thing will be faster in comparison of DP_Create method. As constructor will be called in every case to instantiate the object. Using DP_Create will introduce an overhead of another method call. Apart from that a check for RunLocal attribute also will make it late a bit. There may be few more traps but that much is sufficient for me to vote for constructor.

 

- Lalit

triplea replied on Friday, July 25, 2008

I would vote for DP_Create for 2 reasons:

1. I dont think that when using the [RunLocal()] the overhead will be that great or even noticable... Unless of course your system is massive and time is of essence but even then I think the benefits of point 2 are greater.
2. Using the DP_Create you centralize your creation code. If in some instances (where DB values are required) you call DP_Create and other you populate default values in a constructor then you dont have consistent code. Also since create is part of a CRUD operation it fits nicely in the Data Access region and makes code more discoverable.

But then again all the above are personal preferences, if anybody feels like using the constructor instead then its up to them really...

mikemir8 replied on Friday, July 25, 2008

Thanks for all the answers. What I am trying to find out is if putting the initialization in the constructor (instead of DP_Create) would break anything. So far what I can gather is that it has more to do with consistency rather than any type of technical constraint.

Do you all agree with this?

- Miguel

tmg4340 replied on Friday, July 25, 2008

No, you won't break anything.  In fact, I'm pretty sure that Rocky shows both methods in his book (I don't have it with me to check.)

There is certainly an argument to be made for using DP_Create (and the RunLocal attribute) for consistency.  They are correct in that it will be slower, merely because you have to go through the DataPortal to get your object built.  But unless time is of the essence in your application, it's not something you're likely to notice.

Having said that, I almost always use contstructors instead of DP_Create.  But that's because the types of applications I write have never had to go to the database to get default values.  So I'm consistent to myself.  Smile [:)]

HTH

- Scott

RockfordLhotka replied on Friday, July 25, 2008

Q Johnson:

DataPortal_Create is really for those circumstances where you need to load your default values from the database.  Why else go all the way to the server for it?

The constructor should usually be the place to set hard-coded default values. 

I am afraid I disagree.

You should always use the factory method and data portal approach to create objects.

If you have hard-coded default values, that's great, just put the RunLocal attribute on your DataPortal_Create() method so it doesn't go across the network.

But setting values in the constructor is problematic:

  1. Any exceptions can be hard to debug
  2. You can't check validation rules on the new values
  3. You introduce a new programming pattern everyone must learn/understand
  4. The constructor is invoked even if you are fetching the object, so then you set the properties twice
  5. CslaDataProvider only calls factories (for when you start using WPF)

 

JoeFallon1 replied on Friday, July 25, 2008

I initially went with the constructor approach in 1.x and it worked but was a mess.

When I converted to 2.x I switched to DP_Create and everything became much cleaner.

I have a Protected method in the DP region called SetDefaults which is Overridable. I place the hard coded values here and always call SetDefaults from both DP Create and Fetch.

If a derived class needs more defaults it is simple to override SetDefaults, add the new code and then call MyBase.SetDefaults to get the rest of them.

Joe

 

Copyright (c) Marimer LLC