Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Let's say I have an assemblyA that has a method which creates an instance of assemblyB and calls its MethodFoo().

Now assemblyB also creates an instance of assemblyC and calls MethodFoo().

So no matter if I start with assemblyB in the code flow or with assemlyA, at the end we are calling that MethodFoo of AssemblyC(). My question is when I am in the MethodFoo() how can I know who has called me? Has it been a call originally from assemblyA or was it from assemlyB?

Is there any design pattern or a good OO way of solving this?

share|improve this question

closed as off topic by maple_shaft Sep 27 '12 at 18:00

Questions on Programmers Stack Exchange are expected to relate to software development within the scope defined by the community. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about reopening questions here.If this question can be reworded to fit the rules in the help center, please edit the question.

there is no inheritance or anything between these classes either. – Blake Sep 27 '12 at 15:20
Simple reflection will tell you at any point your current methods calling method. You don't need a full stack trace for this. This question probably belongs on StackOverflow. – Jimmy Hoffa Sep 27 '12 at 15:25
@JimmyHoffa The question is looking for generic OO ways of doing this (unlike the initial version of my answer below). – akton Sep 27 '12 at 15:28
Could you make assemblyA and assemblyB inherit from assemblyC so they both have access to this method? Or, could MethodFoo() be made static so you don't actually need to make an object of that class to call it? – Tyanna Sep 27 '12 at 15:29
why would you need to? if you need different behavior create different methods or pass a parameter – ratchet freak Sep 27 '12 at 15:33
up vote 1 down vote accepted

I am not aware of any generic or common patterns across programming languages. Most handle it by dedicated reflection APIs.

In .Net use the System.Diagnostics.StackFrame and System.Diagnostics.StackTrace classes. See for an example. Other languages and environments may have equivalents.

share|improve this answer
Yep but is there a object oriented way of solving this? so to avoid StackTrace – Blake Sep 27 '12 at 15:21
@BDotA: If you care who called you, you're not doing OOP. Rethink what you are trying to do. (I admit, .NET is often not OO and and we have to leave OO behind sometimes when using it, but it pays to know that we're doing this, even if we have to do it anyway.) – RalphChapin Sep 27 '12 at 20:48

I'm going out on a limb here and guessing you're looking for object oriented techniques for implementing instrumentation.

There are two immediate ways that come to mind, most commonly used would be the first I'm guessing:

  1. Have a global (singleton or what have you) stack somewhere with which every method that executes immediately adds itself to. effectively maintaining a global call chain. You could but don't have to pop at the end of each method you're trying to instrument, common other instrumentation practices are to start a stopwatch at the beginning of your method and stop at the end to record the length etc.

  2. Have a DI type framework that is a router for all method calls, which might behave more akin to message passing, and inside of this framework you would jot down in a stack every method call that occurs similar to above except it would be centralized to this one place.

I can't say I suggest #2 without maybe using some AOP framework or something but in all, maintaining your own stack trace on 100% of method calls is a bit of an extreme instrumentation in my eyes. Great for debugging type stuff and perhaps necessary if you aren't working in a reflexive language, but I would be sure I could turn anything like that off easily for production and do my best to keep it out of the way, which is why I don't really like #2 above.

Neither of these is necessary inside a reflexive language and should therefore not be implemented in C# except to illustrate crossing process boundaries. (caveat: they might be faster than reflection if done right, but the maintenance cost still makes them not worth it)

share|improve this answer
Thanks for the ideas, so in C# how can I do it with Reflection? I dunno if I can move this post to SO ? or copy paste and create a new post in SO a good if you could help me with Reflection way would be great. – Blake Sep 27 '12 at 15:58
@BDotA Look at… though I thought I recalled a way without invoking the StackFrame object I haven't been able to find it. Even still the techniques above should not be done in C#, rather you should use the StackFrame if necessary. – Jimmy Hoffa Sep 27 '12 at 16:05

IMHO you should ask yourself seriously why you think you need this.

If MethodFoo() behaves differently if called from assembly A or B, then the calling assembly is something like a hidden input parameter to MethodFoo() and may probably become the cause for unexpected or erroneous behaviour. So as an alternative, make that input parameter explicit: add an additional parameter to MethodFoo() which indicates the context or caller. This could be an enum, a string parameter or a reference to the calling assembly itself, depending on the intended behaviour change of MethodFoo().

share|improve this answer
Oh dear I didn't even imagine he was trying to control flow, that's a very scary thought... Clearly you are a great deal more pessimistic than I to have come up with that conclusion, but sadly you may be right.. – Jimmy Hoffa Sep 27 '12 at 16:17
@JimmyHoffa: if someone asks a question like this without mentioning anything about his intention, I get suspicious ;-) – Doc Brown Sep 27 '12 at 16:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.