By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,934 Members | 1,527 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,934 IT Pros & Developers. It's quick & easy.

Finding if an object references indirectly another object withreflection

P: n/a
Hi,
I was wondering if there was a way with Reflection to find dynamically
if an object was referencing indirectly another object.

A simple example would be:

Object1
|
--Object2
|
---Object3
|
---Object4

Where the Object1 has a reference to Object2 which in turn has a
reference to Object3 and so on. I would like to determine if Object1
has an indirect reference to the Object4 using Reflection.

Obviously that is a simple example but it could be much more
complicated (list of objects, dictionaries, ...).

Anybody knows a way to do that? Is it possible?

Thanks in advance!
Jonathan
Aug 20 '08 #1
Share this Question
Share on Google+
7 Replies


P: n/a
On Wed, 20 Aug 2008 09:11:19 -0700, <jo******@hotmail.comwrote:
Hi,
I was wondering if there was a way with Reflection to find dynamically
if an object was referencing indirectly another object.
Assuming that all of the data structures involved are 100% managed code,
sure. You could enumerate every field of each object recursively,
traversing the tree defined by the references. But it would be _slow_.

IMHO a better answer is to try to find out why you're wanting to do this,
and to attempt to persuade you that there's a better way to solve whatever
design problem it is you're trying to solve. :)

Pete
Aug 20 '08 #2

P: n/a
On Aug 20, 1:52*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Wed, 20 Aug 2008 09:11:19 -0700, <jopro...@hotmail.comwrote:
Hi,
I was wondering if there was a way with Reflection to find dynamically
if an object was referencing indirectly another object.

Assuming that all of the data structures involved are 100% managed code, *
sure. *You could enumerate every field of each object recursively, *
traversing the tree defined by the references. *But it would be _slow_.

IMHO a better answer is to try to find out why you're wanting to do this,*
and to attempt to persuade you that there's a better way to solve whatever *
design problem it is you're trying to solve. *:)

Pete
Thanks for your answer. The problem I am trying to solve is related to
logging. I have a Logger singleton object that is used throughout my
code. I am trying to find a way to enable logging on specific objects.
With my previous example, let's assume that you have 100 instances of
Object1, you will obviously also have 100 instances of Object4. What I
want to do is enable logging only to specific instances of Object1 and
its indirectly referenced object Object4. In other words, I want to
avoid getting debug from all of object instances but from one instance
at a time.

I know that the common solution for this problem is to pass an object
reference to all the children of Object1 at their creation so that
they aware of the root parent and they can determine if logging is
enabled or not. For a simple architecture like this, it's not a
problem, but for a much bigger architecture, this solution would
"clog" the code as I need to add a parameter for each of my
constructor of each of my class.

So I was trying to find another solution around this problem. I tought
about recursevely browsing all the members as you mentionned, but the
speed hit would indeed be a problem.

Any thoughts?

Jonathan

Aug 20 '08 #3

P: n/a
If the Objects are known then there is no need to use reflection. You
can just use the as keyword in C# for example
bool IsObject4(Object1 toBeTested)
{
Object4 test = toBeTested as Object4;
return(test != null);
}

Hope this helps
Leon Lambert

jo******@hotmail.com wrote:
Hi,
I was wondering if there was a way with Reflection to find dynamically
if an object was referencing indirectly another object.

A simple example would be:

Object1
|
--Object2
|
---Object3
|
---Object4

Where the Object1 has a reference to Object2 which in turn has a
reference to Object3 and so on. I would like to determine if Object1
has an indirect reference to the Object4 using Reflection.

Obviously that is a simple example but it could be much more
complicated (list of objects, dictionaries, ...).

Anybody knows a way to do that? Is it possible?

Thanks in advance!
Jonathan
Aug 21 '08 #4

P: n/a
bool IsObject4(Object1 toBeTested)
{
Object4 test = toBeTested as Object4;
return(test != null);
}

This is true if I was checking for inheritance, but I want to check
for composition. Object1 has a reference to Object2. Object2 has a
reference to Object3 and Object3 has a reference to Object4. The goal
is to determine if Object1 has an indirect reference to Object4
(Object1->Object2->Object3->Object4).

But thanks anyway,
Jonathan
Aug 21 '08 #5

P: n/a
On Aug 20, 11:45*am, jopro...@hotmail.com wrote:
I know that the common solution for this problem is to pass an object
reference to all the children of Object1 at their creation so that
they aware of the root parent and they can determine if logging is
enabled or not. For a simple architecture like this, it's not a
problem, but for a much bigger architecture, this solution would
"clog" the code as I need to add a parameter for each of my
constructor of each of my class.

So I was trying to find another solution around this problem. I tought
about recursevely browsing all the members as you mentionned, but the
speed hit would indeed be a problem.

Any thoughts?
I would stick to the common solution. Net languages are not built for
speed. Just try resizing a window on a Form and see how much
processor time it eats up. And you're worrying about performance?

RL
Aug 21 '08 #6

P: n/a
On Wed, 20 Aug 2008 11:45:22 -0700, <jo******@hotmail.comwrote:
Thanks for your answer. The problem I am trying to solve is related to
logging. I have a Logger singleton object that is used throughout my
code. I am trying to find a way to enable logging on specific objects.
With my previous example, let's assume that you have 100 instances of
Object1, you will obviously also have 100 instances of Object4. What I
want to do is enable logging only to specific instances of Object1 and
its indirectly referenced object Object4. In other words, I want to
avoid getting debug from all of object instances but from one instance
at a time.

I know that the common solution for this problem is to pass an object
reference to all the children of Object1 at their creation so that
they aware of the root parent and they can determine if logging is
enabled or not. For a simple architecture like this, it's not a
problem, but for a much bigger architecture, this solution would
"clog" the code as I need to add a parameter for each of my
constructor of each of my class.
To some extent, it's hard to provide really good advice because we really
don't know enough about your overall design. For example, do _all_
objects in your design have the capability to participate in logging? Is
logging an inherent part of the architecture, or is it some sort of
debugging helper? And how do you enable logging for a specific object? Is
this managed outside of the object, or is the object itself somehow aware
of its participation in logging?

I would say that, assuming you otherwise have no natural hierarchical
relationship between your objects, one approach would be to have each
loggable object implement an interface (whether you actually define a new
interface for the purpose or just make it part of your class design
doesn't matter) in which the object itself is told to enable or disable
logging. Then each object would manage its own state as well as forward
any state changes to child objects. In this way, the logging state can
propagate down to the children.

Obviously this only works if all the objects know about logging.

The other wrinkle here is that I would say that if there's otherwise no
natural hierarchical relationship between the objects, I question whether
it makes sense to say that if "parent" object Object1 has logging enabled,
"child" object Object4 should as well. After all, if the objects don't
have an explicit hierarchical relationship, it's possible that Object4
could be shared by objects, or have no parent at all. Again, hard to say
for sure without knowing more about your design, but it seems to me that
you've got a sort of chicken/egg thing here. That is, if your design
doesn't lend itself to hierarchical management of the logging, then
perhaps that in and of itself suggests that hierarchical management of
logging isn't really what you want to do.
So I was trying to find another solution around this problem. I tought
about recursevely browsing all the members as you mentionned, but the
speed hit would indeed be a problem.

Any thoughts?
Well, other than the above, you could cache the FieldInfo instances for
each type you're using so that you don't have to keep retrieving them each
time you want to traverse the hierarchy. That would at least eliminate
some of the performance issue. But really, my general rule of thumb is
that if you find yourself reaching for reflection to do things that aren't
inherently about the type system, that usually means it'd be better to go
back and rework the part of the design that led to that in the first place
so that you don't need reflection.

Pete
Aug 21 '08 #7

P: n/a
To some extent, it's hard to provide really good advice because we really*
don't know enough about your overall design. *For example, do _all_ *
objects in your design have the capability to participate in logging? *Is *
logging an inherent part of the architecture, or is it some sort of *
debugging helper? And how do you enable logging for a specific object? *Is *
this managed outside of the object, or is the object itself somehow aware*
of its participation in logging?
Basically we would like to give the ability to all objects to output
debug traces for debugging purposes. Each object register itself to a
singleton Logger object with a name that identifies the type of the
object.

The logging is controlled by Telnet, so with a Telnet console, we send
commands to the Logger to enable/disable logging on certain object
types. The problem is that we differentiate the objects by their types
and not by their instances.
I would say that, assuming you otherwise have no natural hierarchical *
relationship between your objects, one approach would be to have each *
loggable object implement an interface (whether you actually define a new*
interface for the purpose or just make it part of your class design *
doesn't matter) in which the object itself is told to enable or disable *
logging. *Then each object would manage its own state as well as forward *
any state changes to child objects. *In this way, the logging state can*
propagate down to the children.

Obviously this only works if all the objects know about logging.
Yes, the problem is I must pass an interface to every object that
needs to use the Logger and it would clutter the code. Since we
already have a lot of classes that would need this, it is not really a
good solution for us. That's why I was searching for another solution.
But I think I don't have a choice and I will probably go for this
solution.

I was thinking maybe Aspect-Oriented programming to inject code
directly in the IL after the compilation, but we are using Dumps and
PDBs to debug application crashes that are running on-site so I am not
sure this would work since the source would be different than the
binaries.
The other wrinkle here is that I would say that if there's otherwise no *
natural hierarchical relationship between the objects, I question whether*
it makes sense to say that if "parent" object Object1 has logging enabled, *
"child" object Object4 should as well. *After all, if the objects don't*
have an explicit hierarchical relationship, it's possible that Object4 *
could be shared by objects, or have no parent at all. *Again, hard to say *
for sure without knowing more about your design, but it seems to me that *
you've got a sort of chicken/egg thing here. *That is, if your design *
doesn't lend itself to hierarchical management of the logging, then *
perhaps that in and of itself suggests that hierarchical management of *
logging isn't really what you want to do.
Yes, the "parent" hierarchy makes sense in our case. We have a service
that connects to one main server on one side and to several remote
systems on the other sides doing some "stuff" between. We can connects
to several hundreds of remote systems. So in my example, Object1
through Object4 are doing the connection to one external system
(well... it is much more complicated than that, but it gives you an
idea :).

One solution would have been to use AppDomains to physically separate
each set of objects that connects to each remote system. I would then
have the possibility to enable/disable the Logging by AppDomain. But
due to some specific restrictions on our system, we unfortunately
cannot do this.
So I was trying to find another solution around this problem. I tought
about recursevely browsing all the members as you mentionned, but the
speed hit would indeed be a problem.
Any thoughts?

Well, other than the above, you could cache the FieldInfo instances for *
each type you're using so that you don't have to keep retrieving them each *
time you want to traverse the hierarchy. *That would at least eliminate*
some of the performance issue. *But really, my general rule of thumb is*
that if you find yourself reaching for reflection to do things that aren't *
inherently about the type system, that usually means it'd be better to go*
back and rework the part of the design that led to that in the first place *
so that you don't need reflection.
After thinking about it, reflection is not an option since it would
give me info about object types but not instances. With reflection I
could probably know that the Object1's type reference indirectly the
Object4's type, but I wouldn't be able to know if a specific instance
of Object1 references a specific instance of Object4.
Pete- Hide quoted text -

- Show quoted text -
Thanks for your time.
Best regards,
Jonathan
Aug 22 '08 #8

This discussion thread is closed

Replies have been disabled for this discussion.