views:

400

answers:

4

.Net 3.5 sp1 available type question ...

Is it possible to "get a handle" or reference to the actual instance of an assembly that called a method? I can get the executing and calling assembly via reflection, but what I'm after is not so much the assembly, but the INSTANCE of that assembly that called method.

Simple example (maybe):

interface IBob
{
  int Id { get; }
  void Foo();
}

public class Bob : IBob
{
  private int _id = 123;

  public int Id
  {
    get { return _id; } 
  }

  public void Foo()
  {
     new OtherAssemblyClass().Bar();
  }
}

public class OtherAssemblyClass
{
  public void Bar()
  {
    //
    // what I want to do here is get a reference 
    // to the calling INSTANCE of IBob and determine
    // Bob's Id ... so something like:
    //
    // int Id = (System.XXX.GetCallingAssemblyInstance() as IBob).Id;
    //
    //
  }
}

The real situation is a bit more complex than this, and precludes the obvious passing of IBob instance as a parameter in OtherAssemblyClass.Bar(), although that may be end result.

Entirely possible I'm just being stupid too, and not seeing obvious. 2 x 4 corrections to skull also welcome.

A: 

Unfortunately you can't get the instance unless it's passed in. You can find out what's calling your method by using the StackTrace.

Pete OHanlon
A: 

Is putting Bar inside Bob an option?

tsilb
A: 

PostSharp is the only way I would know of to make that work. Take a look at the InstanceBoundLaosEventArgs class. Warning: this is a pretty big deal, and a serious addition to the weight and complexity of your architecture, especially at build time.

Chris McCall
A: 

I can get you halfway there if you are willing to use extension methods. Here's an example:

public static void Bar(this IBob CallingIBob)
{
    int Id = CallingIBob.Id;
}

...and calling Bar():

public class Bob : IBob
{

    #region IBob Members

    public void Foo()
    {
        this.Bar();
    }

    public int  Id
    {
        get { throw new NotImplementedException(); }
    }

    #endregion
}

Yes, it's not the exact case you were looking for, but functionally similar. Bar can be called from any bob and it will have a reference to the calling bob without explicitly passing in the instance.

I understand that you may want to call Bar in another assembly of your choice. Maybe Bar is defined in a base class and you are calling specific implementations of it in subclasses. That's ok, use the extension method to take in information about the specific Bar you are trying to access and route accordingly.

Please update your post with a more concrete problem definition if you would like a more specific solution.

Robert Venables