events that fire events that fire events....a bad thing?

D

Daniel

Hi,

I have a scenario where a class is wrapped inside another but the inner
class triggers an event. I want that event to be accessed outside of the
wrapper. As a result i do code such as:

public Table()
{
_Logic = LogicFactory.Instance.GetLogic();
_Logic.MoveDone += OnMoveDone;
}

public void OnMoveDone(int tableId, int? playerId, bool bBroadCast)
//fired by event in _Logic class
{
MoveDone (tableId, playerId, bBroadCast); //trigger event for
this wrapper class
}


So my query is, the above way of doing this is ok? Or is there some way i
canmake the MoveDone event in _Logic available to an external class directly
without the need for a seemingly redundant inner method. Something like:

public event MoveDoneEvent
{
get { return _Logic.MoveDone; }
}

Thanks
 
B

Bruce Wood

Hi,

I have a scenario where a class is wrapped inside another but the inner
class triggers an event. I want that event to be accessed outside of the
wrapper. As a result i do code such as:

public Table()
{
_Logic = LogicFactory.Instance.GetLogic();
_Logic.MoveDone += OnMoveDone;
}

public void OnMoveDone(int tableId, int? playerId, bool bBroadCast)
//fired by event in _Logic class
{
MoveDone (tableId, playerId, bBroadCast); //trigger event for
this wrapper class
}

So my query is, the above way of doing this is ok? Or is there some way i
canmake the MoveDone event in _Logic available to an external class directly
without the need for a seemingly redundant inner method. Something like:

public event MoveDoneEvent
{
get { return _Logic.MoveDone; }

}

The way you've done it is a common idiom. The only other way I know of
is to expose the actual inner class, something like:

public Logic Logic
{
get { return this._logic; }
}

but one generally doesn't want clients messing directly with internal
objects, so this isn't commonly used.
 
B

Bob Powell [MVP]

Not only is this not "commonly used" I think that it's certainly an
architectural disaster waiting to happen.

My advice would be to NEVER expose a field in such a way and even if the
propagation of events in the manner described seems inelegant, as far as
performance goes the overhead is negligible.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
B

Bruce Wood

Sorry, but I disagree.

There are several places in the Framework in which a class held as a
private instance is designed to be exposed through the wrapper class's
public properties. This usually happens when the class in question is
an aggregate.

ListViewItemCollection comes to mind: ListView doesn't just expose
methods / properties / events on its collection of list view items.
Instead, it exposes the collection via the Items property and lets you
work directly with it. The collection class, however, was designed
from the outset to protect its contents and let the caller do only
reasonable things with it.

It really all depends upon why your wrapper class is holding the inner
instance. If the outer class serves no other purpose than to wrap the
inner class, then I agree that it is better to link the inner class's
events / properties / etc through the outer class, thus making it
appear that the outer class implements them.

If, however, the outer class is doing a bunch of other things, and the
functions of the contained class are incidental to the outer class's
main function, it might be better to expose the contained class,
providing that it was carefully designed to not allow tampering from
sneaky client code. Again, ListViewItemCollection being an example in
the Framework of this approach.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top