I'm needing to implement a ReadOnlyChildList. Specifically, I need a collection that instantiates as the EditableChildCollection does (accepting a SafeDataReader) but has the 'readonly' functionality of the ReadOnlyList. The only way I'm seeing to do this is to actually implement an EditableChildList and override the Add/Remove/etc... methods. Is that my only option, or is there something better I'm missing?
Noooooooooooooooooooooo......
Just add a readonly property in you Editable Root Object.
c# (in your editable root object...)
private SomeListBO _someList = null;
public SomeListBO SomeList
{
get
{
if (this._ someList == null)
{
this._someList = SomeListBO.GetList();
}
return (this._someList);
}
}
Thas is it. You now have a readonly list tied to your editable root object.
Hope this helps
guyroch,
Yes, thank you and understood...but doesn't the implementation you're suggesting allow me to still:
editableRootObject.SomeList.Add(anItem);
I don't want a UI client to be able to do that, therefore my thinking that a ReadOnlyList is in order. But, I also need to instantiate that collection by passing it a SafeDataReader (containing a second result set).
No. it won't allow you to add an item. By default, ReadOnlyList in CSLA will not let you do this.
The only time you can _add_ objects in your ReadOnlyList is when its IsReadOnly variable is set to false. Typically you will set the IsReadOnly variable to false in the dp_fetch method and then set it back to true before leaving the dp_fetch.
ReadOnlyList means just that, READONLY, so it won't allow you to add an item other than inside your dp_fetch method... unless of course you forget to set it back to IsReadOnly = false at the end of your dp_fetch. But if you do, its a bug :)
...and... make sure your list (SomeListBO) inherits from ReadOnlyListBase and not BusinessListBase...
guyroch,
Ok then, now I'm back where I started. I had presumed that ReadOnlyList was necessary in order to get the behavior I require. But, I'm struggling with how to implement ReadOnlyList as a "child" ReadOnlyList where I pass the GetReadOnlyList factory method a SafeDataReader as opposed to Criteria arguments. Or, is that just it...do I pass the SafeDataReader through the Criteria class?
(Edit: This "child" behavior is desired because my SafeDataReader already contains the result set for the ReadOnlyList retrieved when I went to the db in dp_fetch for the EditableRootObject)
Why do you want to pass the SafeDataReader?
Doing it this way will _lazy_load_ your list - a great performance improvement IMHO. By that I mean it will get loaded only when you make a call to it. Your db_fetch inside your ReadOnlyList will create it own instance of SafeDataReader and will load itself.
public SomeListBO SomeList
{
get
{
if (this._ someList == null)
{
this._someList = SomeListBO.GetList();
}
return (this._someList);
}
}
Nothing prevents you to create a Criteria class (and Factory mehtod) that take in your Editable Root Object ID so that you dp_fetch inside your ReadOnlyList loads only what it needs.
this._someList = SomeListBO.GetList(MyRootBO.ObjectId);
"This child behavior is desired because my SafeDataReader already contains the result set for the ReadOnlyList retrieved"
And change your query to only return the Root BO data.
Then when your request the ROC you can either get all records or pass in a simple criteria to it like Root.ID to narrow down the list.
Joe
Based on the lazy load code above your ROC will only be fetched once and then you can use it multiple times. I think this is a better solution than hitting the DB everytimeCanAddObject is called. Most users are used to logging out and back in to "pick up" any new permissions/rights. I do not think the perms need to be live 100% of the time.
Joe
Copyright (c) Marimer LLC