locked
Caller information

    Question

  • According to:

    http://msdn.microsoft.com/en-us/library/hh534540%28v=vs.110%29.aspx

    there are some attributes in which you can add to a parameter to get information about who is calling the method.


    Is there a attribute to get the object instance who called a method?

    Something like

    public void SomethingImportant(string message, [CallerInstance] object caller = null) {

    if (caller != Parent && _locked)

    throw new InvalidOperationException("You cannot do this while the object is locked")

    ... }

    Or something like:

        public static class Log
        {
            public static void Debug(object message, [CallerInstance] object caller = null)
            {
                ILog logger = LogManager.GetLogger(caller.GetType());
                logger.Debug(message);
            }
        }

    this could enforce that no one is logging in the name of someone else

    (or in this case, maybe [CallerType])

    i would like to have something that passes "this" as the parameter to the function, without the chance of someone using another object as "this"

    Replacing

    [CallerInstance] object caller = null

    with thisat compile time,

    so

    [CallerInstance] ISomething caller = null

    would only compile if it is being called by a ISomething


    Sunday, March 18, 2012 2:02 PM

Answers

  • "Is there an attribute to get the object instance who called a method?"

    Apparently no such attribute exists at this time.  The attributes provide information for diagnostic purposes.  It does not appear to be something to use for the purpose that you seek.

    http://msdn.microsoft.com/en-us/library/system.security.permissions.aspx   

    You would use attributes defined in the System.Security namespace to define code security.  What purpose would getting the object instance serve?  How would the code determine the type of the object instance?  Using Reflection requires that the type's assembly be accessible to your code. 

    If your logger is a service, it would not be able to perform Reflection and determine the assembly's type.  As you have already noted, the potential exists for anybody or anything to call your code from almost anywhere.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Sunday, March 18, 2012 3:28 PM
    Moderator
  • For your logger service you can use the StackFrame class to solve the issue where some caller can pretend to be another caller:

    public static void Log(string message)
    {
        StackFrame sf = new StackFrame(1, true);
        MethodBase callingMethod = sf.GetMethod();
        Type type = callingMethod.DeclaringType;
        string methodName = callingMethod.Name;
        string fileName = sf.GetFileName();
        int lineNumber = sf.GetFileLineNumber();
    
        // Log Information
    }

    In the example above, there is no way a method to the info of another method when calling Log, however note the following:

    1- There is no way to get the caller instance using StackFrame. Actually if the caller is a static method there will be no instance. Also if you have a release version it's possible that the "this" object of the caller would be garbage collected by the time Log is called.

    2- You can get FileName and LineNumber from StackFrame only if you include Debugging information (.pdb file). Otherwise the only information available is method name of the caller.

    3- You may get false information if optimization is enabled the the JIT compiler decides to inline a Method.
    For example: Method1 calls Method2, Method2 calls Log. If Method2 is too small and the JIT compiler chooses to make it inline (to optimise performance), then your Log method will see that Method1 did the call instead of Method2.


    http://sherifelmetainy.blogspot.com/

    Sunday, March 18, 2012 5:08 PM

All replies

  • "Is there an attribute to get the object instance who called a method?"

    Apparently no such attribute exists at this time.  The attributes provide information for diagnostic purposes.  It does not appear to be something to use for the purpose that you seek.

    http://msdn.microsoft.com/en-us/library/system.security.permissions.aspx   

    You would use attributes defined in the System.Security namespace to define code security.  What purpose would getting the object instance serve?  How would the code determine the type of the object instance?  Using Reflection requires that the type's assembly be accessible to your code. 

    If your logger is a service, it would not be able to perform Reflection and determine the assembly's type.  As you have already noted, the potential exists for anybody or anything to call your code from almost anywhere.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Sunday, March 18, 2012 3:28 PM
    Moderator
  • For your logger service you can use the StackFrame class to solve the issue where some caller can pretend to be another caller:

    public static void Log(string message)
    {
        StackFrame sf = new StackFrame(1, true);
        MethodBase callingMethod = sf.GetMethod();
        Type type = callingMethod.DeclaringType;
        string methodName = callingMethod.Name;
        string fileName = sf.GetFileName();
        int lineNumber = sf.GetFileLineNumber();
    
        // Log Information
    }

    In the example above, there is no way a method to the info of another method when calling Log, however note the following:

    1- There is no way to get the caller instance using StackFrame. Actually if the caller is a static method there will be no instance. Also if you have a release version it's possible that the "this" object of the caller would be garbage collected by the time Log is called.

    2- You can get FileName and LineNumber from StackFrame only if you include Debugging information (.pdb file). Otherwise the only information available is method name of the caller.

    3- You may get false information if optimization is enabled the the JIT compiler decides to inline a Method.
    For example: Method1 calls Method2, Method2 calls Log. If Method2 is too small and the JIT compiler chooses to make it inline (to optimise performance), then your Log method will see that Method1 did the call instead of Method2.


    http://sherifelmetainy.blogspot.com/

    Sunday, March 18, 2012 5:08 PM