There is allways a Public Add method in BusinessListBase?

There is allways a Public Add method in BusinessListBase?

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


correodemarques posted on Friday, December 07, 2007

Hi everybody, I'm sorry to insist in this, but is something that worries me:

BusninessListBase inherits at some point from Collection(of T) and therefore has a Public Sub Add(item As T). What if I want a collection of child objects with its Add method Friend in scope?

This case is present when the parent object have two (or more) collections of child objects and the insert and remove operation of all of them are related (for example a remove operation for collection #1 triggers an insert operation for collection #2) and I want to control that behavior from the parent object.

Greetings from sunny Cancun!! and, as allways, forgive my mistakes in english.

RockfordLhotka replied on Saturday, December 08, 2007

I usually make my child objects have Private constructors and Friend factory methods. This way the UI can't create an instance of a child object, and so they are unlikely to add a child object to a collection.

correodemarques replied on Saturday, December 08, 2007

Ok, that's the way I'm doing it too (following your instructions in the book, of course Smile [:)]). But in this case in particular I still have a problem, like I said before, the Add/Remove operations in my child collections (in this case) are related, so I have this:

Public Class Parent

#Region " Business Methods "
  Private grantedRoles As RolesCol = ...
  Private restOfRoles As RolesCol = ...

  Public Sub AddRole(RoleId As...)
    Dim item As Role = restOfRoles(RoleId)
    grantedRoles.Add(item)
    restOfRoles.Remove(item)
  End Sub

  Public Sub Remove Role(RoleId As ...)
    Dim item As Role = grantedRoles(RoleId)
    restOfRoles.Add(item)
    grantedRoles.Remove(item)
  End Sub
#End Region

#Region " Data Access "
  Protected Sub Dataportal_Update

     ...update Parent Data...

     'Update grantedRoles
     grantedRoles.Update

    'Don't update restOfRoles
    'restOf Roles is just a helper collection, so its data is not in the database

  End Sub
#End Region

End Class

The problem: If the Add method in RolesCol is Public, the UI can take an item from restOfRoles collection and insert it into grantedRoles collection directly (without use AddRole method in Parent class)

Anyway that is the way I do this in CSLA 1.x. I guess now I'm going to forget about the AddRole and RemoveRole in the Parent class, and figure something out, maybe overriding the InsertItem method from Collection(of T) to tell the Parent object that a role is changing places.

Thank you very much Rocky for you reply, and have a good weekend. Let me say too that I'm a big fan of your work. Every body here at work use CSLA with wonderful results.

Saludos desde Cancun! And to the beach tomorrow!

swegele replied on Monday, December 10, 2007

I am also curious about how to hide that Add(item As T) method from the public view...preferrably I would like to do it in my base class where I hide other things too.

<Serializable()> _

Public MustInherit Class JTBusinessListBase(Of T As JTBusinessListBase(Of T, C), C As Csla.Core.IEditableBusinessObject)

Inherits BusinessListBase(Of T, C)

One other thing I do is to Shadow the AllowEdit property to be ReadOnly...and added a protected sub SetAllowEdit.  It gets rid of all the public stuff that our users would get confused with anyway.

CSLA pattern is so nice in that I only expose the bare minimum at the public level. 

I have tried several ways to hide Add() in the base class but I can't figure it out.  Would I have to do something in each collection class?

RockfordLhotka replied on Monday, December 10, 2007

I don’t recommend this, but…

 

You can always shadow Add as a private member. In VB this is done with the Shadows keyword, and in C# with the new keyword.

 

It is a bad idea, because it breaks polymorphism (you are literally removing a method that should be exposed via the base class), but it does work.

 

Private Shadows Sub Add(item As T)

End Sub

 

Rocky

 

 

From: swegele [mailto:cslanet@lhotka.net]
Sent: Monday, December 10, 2007 9:38 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] There is allways a Public Add method in BusinessListBase?

 

I am also curious about how to hide that Add(item As T) method from the public view...preferrably I would like to do it in my base class where I hide other things too.

<Serializable()> _

Public MustInherit Class JTBusinessListBase(Of T As JTBusinessListBase(Of T, C), C As Csla.Core.IEditableBusinessObject)

Inherits BusinessListBase(Of T, C)

One other thing I do is to Shadow the AllowEdit property to be ReadOnly...and added a protected sub SetAllowEdit.  It gets rid of all the public stuff that our users would get confused with anyway.

CSLA pattern is so nice in that I only expose the bare minimum at the public level. 

I have tried several ways to hide Add() in the base class but I can't figure it out.  Would I have to do something in each collection class?



swegele replied on Monday, December 10, 2007

Tried your method and it doesn't work if I do it on the base class...only if I do it on the actual business list class itself.  It still shows up publically as an overload of Add(item as T).

It is strange on 2 accounts:

1.  Because literraly item As T is showing up to the user...I would think intellisense would show the correct type instead of T

2.  Still shows up publically even though I shadow it in the base class as private or friend

 

RockfordLhotka replied on Monday, December 10, 2007

Shadowing is limited, and works in an almost opposite way from virtual methods.

 

Shadowing works based on the type of the VARIABLE you are using, not the type of the OBJECT you are using.

 

In other words, shadowing only works if the variable is the same as the type of the class that does the shadowing.

 

Dim x As CustomerList

x.Add(…)

 

Add() will be unavailable only if CustomerList is the type that shadowed the method.

 

But shadowing is the only option I’m aware of for this issue.

 

Rocky

 

 

From: swegele [mailto:cslanet@lhotka.net]
Sent: Monday, December 10, 2007 9:57 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: There is allways a Public Add method in BusinessListBase?

 

Tried your method and it doesn't work if I do it on the base class...only if I do it on the actual business list class itself.  It still shows up publically as an overload of Add(item as T).

It is strange on 2 accounts:

1.  Because literraly item As T is showing up to the user...I would think intellisense would show the correct type instead of T

2.  Still shows up publically even though I shadow it in the base class as private or friend

 



swegele replied on Monday, December 10, 2007

OK that makes sense why it only works when I shadow it on the class and not just the base class.

But if I don't do anything...(meaning no shadowing or funky stuff)...why does the method Add(item As T) show up to a consumer of my business objects? 

I would think it would show the actual type like Add(item as Customer) or whatever?

 

swegele replied on Monday, December 10, 2007

I mean intellisense for a consumer of the business list literally see's "T" and not "Customer" or whatever the class actually is.

ajj3085 replied on Tuesday, December 11, 2007

Probably your best bet is to override Add and have it always throw a NotSupportedException.  That way you're not breaking encapsulation, and Add won't function from the public API.

swegele replied on Tuesday, December 11, 2007

Thanks ajj3085,

2nd issue is I don't understand why intellisense would show a "T" instead of the actual type.  If I use generics to make a list of type Customer, isn't the Add supposed to look like this in intellisense Add(item as Customer).  Mine doesn't.  Mine looks like this Add(item as T).

Is this because I have my own base class JTBusinessListBase that inherits from Rocky's?  Any body else seen this problem?

 

ajj3085 replied on Tuesday, December 11, 2007

What does your collection class declaration look like? 

swegele replied on Tuesday, December 11, 2007

The base class that inherits from Rocky's is

<Serializable()> _

Public MustInherit Class JTBusinessListBase(Of T As JTBusinessListBase(Of T, C), C As Csla.Core.IEditableBusinessObject)

Inherits BusinessListBase(Of T, C)

 

The actual class (akin to customer) that I use is this

<Serializable()> _

Public Class JTCaseRequestList

Inherits JTBaseObjects.JTBusinessListBase(Of JTCaseRequestList, JTCaseRequest)

ward0093 replied on Saturday, November 22, 2008

I needed to bring this topic/thread back up because of something i am noticing here with my Developers.

a lot of places they are using the Add/Insert/Remove methods... instead of AddItem/InsertItem/RemoveItem.

I want to physically hide the first set of options so it does not even come up in the list of methods?  I want to do this so the Devs here will be forced to use AddItem, etc.  I saw the previous posts on encapsulation... but does anyong have a better idea to hide these methods?

Also, what are the consequences with using the <Obsolete> Attribute instead?  Is there some overhead with this attribute?

ward0093

sergeyb replied on Saturday, November 22, 2008

There is no overhead, it is only used by compiler, not run time.

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

cid:_2_0648EA840648E85C001BBCB886257279
Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: ward0093 [mailto:cslanet@lhotka.net]
Sent: Saturday, November 22, 2008 11:35 AM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: RE: There is allways a Public Add method in BusinessListBase?

 

I needed to bring this topic/thread back up because of something i am noticing here with my Developers.

a lot of places they are using the Add/Insert/Remove methods... instead of AddItem/InsertItem/RemoveItem.

I want to physically hide the first set of options so it does not even come up in the list of methods?  I want to do this so the Devs here will be forced to use AddItem, etc.  I saw the previous posts on encapsulation... but does anyong have a better idea to hide these methods?

Also, what are the consequences with using the <Obsolete> Attribute instead?  Is there some overhead with this attribute?

ward0093



Copyright (c) Marimer LLC