Reputation: 17196
I want to write some kind of debugging tool for my MVC application which is hosted on production hosting environment where I have very limited access and no way to debug the code except like writing each line of code to .txt file. For example let's say I have a code:
public void Foo()
{
var bar = new Bar();
var baz = new Baz();
bar.Qux(baz);
}
What I'm actually doing now is:
public void Foo()
{
MyTxtDebugger.Write("Enter Foo()")
MyTxtDebugger.Write("var bar = new Bar();")
var bar = new Bar();
MyTxtDebugger.Write("var baz = new Baz();")
var baz = new Baz();
MyTxtDebugger.Write("bar.Qux(baz);")
bar.Qux(baz);
MyTxtDebugger.Write("Exit Foo()")
}
Where MyTxtDebugger.Write
is my custom simple text writer. This kind'a does it's thing but I want to make the code much cleaner and do not duplicate the actual code line to a string. What I want to have is this:
public void Foo()
{
[MyTxtDebugger] var bar = new Bar();
[MyTxtDebugger] var baz = new Baz();
[MyTxtDebugger] bar.Qux(baz);
}
Or at least this:
public void Foo()
{
MyTxtDebugger.Write(); var bar = new Bar();
MyTxtDebugger.Write(); var baz = new Baz();
MyTxtDebugger.Write(); bar.Qux(baz);
}
I want the output of MyTxtDebugger.Write()
to be "MyTxtDebugger.Write(); var bar = new Bar();"
. Is this possible and if so, how? I've already studied, for example, this question but in this case the actual C# code is not captured in the output.
Upvotes: 2
Views: 692
Reputation: 15794
Hmm... I don't know exactly what you are looking for, but if you're trying to do what loggers already do, then you should be looking at Environment.StackTrace
:
https://msdn.microsoft.com/en-us/library/system.environment.stacktrace(v=vs.110).aspx
FullClassName The full name of the class, including the namespace.
MethodName The name of the method.
MethodParams The list of parameter type/name pairs. Each pair is separated by a comma (","). This information is omitted if MethodName takes no parameters.
FileName The name of the source file where the MethodName method is declared. This information is omitted if debug symbols are not available.
LineNumber The number of the line in FileName that contains the source code from MethodName for the instruction that is on the call stack. This information is omitted if debug symbols are not available.
I hope this was what you're talking about. Oh, and remember to update your Release and Debug build targets to output full debug symbols. Debug symbols are your friend.
Upvotes: 0
Reputation: 73502
Short answer : no.
Long answer:
There is nothing available out of the box which does what you're looking for.
Also the pseudocode you proposed with [MyTxtDebugger]
attribute kinda stuff isn't going to work because it isn't a valid c# syntax. You can't apply attributes to local variables/statements.
PostSharp comes to my mind when playing these kind of magic. It does post-compilation and rewrites your IL. PostSharp Logging will come closer but not exactly what you're looking for. It can log when you enter/exit some method. Can't write each and every statement being executed. If that's okay for you, go for it.
If you really need exactly what you're looking, then all I can think of is writing your own IL weaver.
It's fairly simple(not so simple!) with Fody. Take a look at PropertyChanged.Fody implementation. It implements INPC at compile time based on the availability of required attribute.
At first PropertyChanged.Fody
can be overwhelming; look at BasicFodyAddin for a good start.
You can write your own fody weaver which looks at the IL, find out the statements, then emit IL to log the statement. (If you do something like this, please open source it too. Will be really useful for others)
Have fun.
Upvotes: 1
Reputation: 86134
It is possible. In DEBUG mode, you can extract file and line information using a stack trace. Here's a proof of concept.
static void Main(string[] args) {
ShowCallerLine(); // hello!
ShowCallerLine(); // goodybye!
}
static void ShowCallerLine() {
var frame = new StackFrame(1, true);
var lineNumber = frame.GetFileLineNumber();
var fileName = frame.GetFileName();
var line = File.ReadLines(fileName).ElementAt(lineNumber - 1);
Console.WriteLine(line);
}
Output:
ShowCallerLine(); // hello!
ShowCallerLine(); // goodybye!
However, I'd advise caution in using a technique like this. It's brittle and prone to failure and unexptected behavior.
Upvotes: 0
Reputation: 11792
With the context of your comments in mind, the answer to your question
Is this possible and if so, how?
Is No. It is not possible.
(Though I'd be happy to delete if someone proves otherwise)
Upvotes: 0