child collection update with interface

child collection update with interface

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


dean posted on Wednesday, October 18, 2006

I have a collection of different types of children, each child implementing an interface iDetail. During the update process the collection interates thru the members and wants to call child.DeleteSelf, child.update, and child.insert. But I don't want these methods to be public so I can't put them in the iDetail interface. I don't see how to create a protected friend interface. What am I missing here?

Dean

skagen00 replied on Wednesday, October 18, 2006

There was a good thread on this as I was bumping into this myself. I ended up using reflection as there were some code generation issues for me.

An option is to do a separate internal interface for IDetailInternal and while looping through your collection of children, just cast them to IDetailInternal and invoke the internal methods.

I'll find that thread and edit my post w/ a link.

http://forums.lhotka.net/forums/thread/6832.aspx

And from another post:

So, what I found worked for me was to cast the object to the internal interface for the purpose of doing the Update/DeleteSelf/Insert.

((IProfileMemberInternal)profileMember).DeleteSelf();

dean replied on Wednesday, October 18, 2006

Thanks for the pointer and I get the drift but I'm a vb guy and that thread is pretty much c# and my translation skills are failing me.

what i tried is declaring a friend protected interface in my child. I then referenced that interface from my collection in my cast statement. is that correct?

Thanks!

ajj3085 replied on Wednesday, October 18, 2006

Ahh...

Declare your interface as Friend only.

Friend Interface IDetailInternal Implements IDetail

Function MyInternalFunction( arg As String ) As String

End Interface

Public Class MyBo Inherits BusinessBase(Of MyBo) Implements IDetailInternal

     Private Function MyInternalFunction( arg As String ) As String Implements IDetailInternal.MyInteralFunction

     Public Property DetailProp As String
     End Property

End Class

malloc1024 replied on Wednesday, October 18, 2006

Yes, that is the way to do it in VB.Net.  To create an explicit interface in VB.NET you set the properties or methods to something other than public in the class that implements the interface.  It is easier to create explicit interfaces in VB.Net than in C#.

ajj3085 replied on Wednesday, October 18, 2006

malloc1024:
It is easier to create explicit interfaces in VB.Net than in C#.


Ok, have to call you out on that..  To implement explicitly, you just do something like this:

string IInterface.MyExplicitProperty {
  // code here
}

What's tough about that?  It seems the VB.net way is more confusing since you're marking the explicitally defined member as private even though its not really private.. I guess private in that case mean's private to the interface?

malloc1024 replied on Wednesday, October 18, 2006

I didn’t mean to say that it was tough to create an explicit interface in C#, just slightly more work to remember how to create one.  I find it easier to create explicit interfaces in VB.Net.  But you are correct that it really isn’t more difficult.  I do use VB.Net more and that may have something to do with my opinion.


I like the fact the interfaces are more explicit in VB.NET.  I also find the way VB.NET handles explicit interfaces less confusing. 

ajj3085 replied on Wednesday, October 18, 2006

malloc1024:
I didn’t mean to say that it was tough to create an explicit interface in C#, just slightly more work to remember how to create one.  I find it easier to create explicit interfaces in VB.Net.  But you are correct that it really isn’t more difficult.  I do use VB.Net more and that may have something to do with my opinion.


That just depends on the language you're most proficient in.

malloc1024:
I like the fact the interfaces are more explicit in VB.NET.  I also find the way VB.NET handles explicit interfaces less confusing.

I'll agree that defining implicit interfaces is more explicit in VB than in C#.  In C#, you don't need to do anything at all, the compiler just matches the signatures up and will say 'yup, I found something matching that interfaces signature, so the interface is implemented.' 

Again, how explicit interfaces are handled depends on your background.. I did alot of VB work until .Net came along.  I also had a strong C++ background from my college days, which is probably why C# makes more 'sense' to me than VB (didn't do much vb before college).

Andy

malloc1024 replied on Wednesday, October 18, 2006

You can use EXPLICT interfaces to hide members of an interface.  The only way to access the private or protected members of an interface is to cast to the interface.  If you place the interface in another assembly, the presentation layer could not cast to it if it doesn’t have a reference to it.  One of the benefits of using explicit interfaces is that it allows you to hide members of an interface.

skagen00 replied on Wednesday, October 18, 2006

Malloc, that's definitely correct. (Talked about a little bit in that first thread).

I would have taken that very route myself if it weren't for the fact that my child objects are generating insert/update/deleteself in partial classes and I didn't feel like manipulating the templates for generation yet. A generated internal method without an explicit implementation declaration throws a compile error.

Here's some sample code from one of my collections where I'm using reflection.

internal void Update(SqlConnection cn, IProfile parent)

{

RaiseListChangedEvents = false;

// loop through each deleted child object and use the internal interface

// to call DeleteSelf for deleted objects

foreach (IProfileRole deletedChild in DeletedList)

deletedChild.GetType().InvokeMember("DeleteSelf", BindingFlags.Instance | BindingFlags.NonPublic |

BindingFlags.InvokeMethod, System.Type.DefaultBinder, deletedChild, new object[] { cn });

DeletedList.Clear();

// loop through each non-deleted child object and use the internal interface

// to call the appropriate method.

foreach (IProfileRole child in this)

{

if (child.IsNew)

child.GetType().InvokeMember("Insert", BindingFlags.Instance | BindingFlags.NonPublic |

BindingFlags.InvokeMethod, System.Type.DefaultBinder, child, new object[] { cn, parent });

else

child.GetType().InvokeMember("Update", BindingFlags.Instance | BindingFlags.NonPublic |

BindingFlags.InvokeMethod, System.Type.DefaultBinder, child, new object[] { cn, parent });

}

RaiseListChangedEvents = true;

}

#endregion //Data Access

 

 

 

ajj3085 replied on Wednesday, October 18, 2006

Probably the best way is what malloc said, use explict interfaces.  I did this recently as well..

I defined an interface as:

internal interface IDetailInternal : IDetail {
// Internal methods only here
}

Then in my implementation, I implemented IDetail members implicitly and IDetailInternal members explicitly.  You don't even need to specify IDetail on your BO, the compiler will create an expanded list for you.

Copyright (c) Marimer LLC