Passing a method's name as a parameter - c#

private void Method1()
{
//Do something
Log("Something","Method1");
}
private void Method2()
{
//Do something
Log("Something","Method2");
}
private void Log(string message, string method)
{
//Write to a log file
Trace.TraceInformation(message + "happened at " + method);
}
I have several methods like Method1 and Method2 above, and i would like some way pass the method's name as a parameter, without manually editing the code.
Is that possible?

As of C# 5, this is really easy using caller info attributes:
private void Method1()
{
//Do something
Log("Something");
}
private void Method2()
{
//Do something
Log("Something");
}
private void Log(string message, [CallerMemberName] string method = null)
{
//Write to a log file
Trace.TraceInformation(message + "happened at " + method);
}
In terms of getting this working:
You must be using the C# 5 (or later) compiler, otherwise it won't know to handle the attributes specially
The attributes have to exist in your target environment. Options there:
In .NET 4.5 the attributes are simply present
For .NET 4 you can use the Microsoft.Bcl NuGet package
For earlier versions of .NET, copy the attribute declaration into your own code, making sure you use the same namespace. When you later move to a new version of .NET, you'll need to remove it again.

Excellent answer from Jon Skeet.
However, if you don't use .NET 4.5 , you can try reflection. How ever you should know that reflection must be used only when it is absolutely necessary. Do not over-use it for the sake of using it.
Coming back,
You could do something like,
using System.Reflection; //include Reflection namespace
Console.WriteLine(MethodBase.GetCurrentMethod().Name) //Get the method-name of the current method
In your case, it would be like below,
private void Method1()
{
//Do something
Log("Something", System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void Method2()
{
//Do something
Log("Something", System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void Log(string message, string method)
{
//Write to a log file
Trace.TraceInformation(message + "happened at " + method);
}
EDIT:
As per the below comments from #Jon Skeet's, if you want .Net 4.5 kind of fancy and neat implementation, check out the Micrsoft.Bcl NUGET Package.

Aspect Oriented Programming (AOP) usually allows to achieve such tasks. You can have a look at the free version of PostSharp, especially the Logging aspect is helpful in your case.
Your code then looks like this:
[LogAspect("Something")]
void Method1(string name)
{
}
You can use PostSharp down to .NET framework 2.0.

Related

Text to Speech C#

So I'm just a uni student who's enjoying programming (1st year) and I've decided to try out some new features.
I came across the speech synthesizer and its reallt interesting, but i have one problem.
Say if I said
Console.WriteLine("Hello");
Is there a way that I could get the program to say that without having to add
Console.WriteLine("Hello");
s.Speak("Hello");
?
Like I'm wondering if I am able to have my program speak whatever I type without adding extra code
Cheers
There is no way you could do that. But what you can try is creating a static method that takes a string value and prints "Hello" on to the console and use the TTS engine, like
static void PrintAndSpeak(string message)
{
Console.WriteLine(message);
s.Speak(message);
}
And then use the method inside the entry point:
PrintAndSpeak("Hello");
You could create a method that would take in your string. That method would print and read the message.
Example (pseudocode)
public void writeAndTalk(string message){
Console.WriteLine(message);
s.Speak(message);
}
And you then use the method wherever you like.
You could create a type to do this for you. Something like:
public class TextAndSpeech
{
private readonly WhateverSIs s;
public TextAndSpeech(WhateverSIs s)
{
this.s = s;
}
public Spurt(string message)
{
Console.WriteLine(message);
s.Speak(message);
}
}
I have no idea what type s is that you're using, so replace WhateverSIs with the actual type.
Using it would look something like:
var spurter = new TextAndSpeech(new WhateverSIs());
spurter.Spurt("Hello");
spurter.Spurt("Another thing.");

Which Method Am I In?

I am aiming to add some #if DEBUG to my methods however I don't want to edit the code I copy and Paste into each method.
Is there a generic piece of code like this:
void DoSomething()
{
#if Debug
Log("Now In " + MethodName);
#endif
}
Where MethodName is populated to equal DoSomething, or whichever Method called the Log?
If you're using .NET 4.5 you can use the CallerMemberName attribute:
public static GetCallerMemberName([CallerMemberName]string caller = null)
{
return caller;
}
Note that when calling this method you don't need to pass anything as an argument - the C# compiler does the work for you. This also means that you avoid performing reflection at runtime, which makes this method much faster.
Usage:
void DoSomething()
{
#if Debug
Log("Now In " + GetCallerMemberName()); // Logs "Now in DoSomething"
#endif
}
System.Reflection.MethodBase.GetCurrentMethod().Name

What is the Behavior of a Dynamic Attribute in a Static (Extension) Class in C# (MVC3)

I am new to developing in .NET and C#, but have been a long-time developer, working with C, C++, Java, PHP, etc.
I have an MVC3 extension class for my data models that refers to the database. It is set as "private static" in the class, but I think that it is not keeping up with database changes. In other words, when I change data in the controllers, those changes aren't "noticed" in the db because it is static. Currently, I am creating and disposing of the variable for each use, to compensate.
My questions are:
Am I correct that a static db variable could behave that way?
Is it necessary to dispose of the dynamic variable in the static class, or will garbage collection still take care of it automatically?
Here is a relevant snippet of the class:
namespace PBA.Models {
using System;
using System.Text.RegularExpressions;
using PBA.Models;
using PBA.Controllers;
public static class Extensions {
private static PbaDbEntities db = null;
public static PbaDbEntities GetDb() {
// TODO: find out about static memory/disposal, etc.
//
if (db != null) {
db.Dispose();
}
db = new PbaDbEntities();
return db;
}
public static string GetCheckpointState(this Activity activity, long memberProjectId) {
GetDb(); // TODO: Do I need to do this each time, or will a one-time setting work?
string state = CheckpointController.CHECKPOINT_STATUS_NOT_STARTED;
try {
var sub = db.ActivitySubmissions.
Where(s => s.activityId == activity.activityId).
Where(s => s.memberProjectId == memberProjectId).
OrderByDescending(s => s.submitted).
First();
if (sub != null) {
state = sub.checkpointStatusId;
}
}
catch (Exception e) {
// omitted for brevity
}
return state;
}
}
}
Your code will fail horribly in production.
DataContexts are not thread-safe; you must not share a context between requests.
Never put mutable objects in static fields in multi-threaded applications.
Ignoring exceptions that way is a terrible idea, if you don't want to handle exceptions just don't try/catch, or catch & rethrow. Think about it like this, after you've buried the exception, your program is in an invalid state, b/c something you have no control over error'd out. Now, b/c you've buried the exception, your program can continue to operate but it's in a bad state.
If your code makes it to production, 3.5 yrs from now some jr. programmer is going to get involved in some middle of the night firestorm because all of a sudden the website is broken, even though it used to work. It will be completely impossible to track down where the exception is happening so, this poor guy is going to spend 48 straight hours adding logging code all over the place to track down the problem. He will find that some DBA somewhere decided to rename the column MemberProjectId to MemberProjectIdentifier, which caused your linq to blow up.
Think of the children, handle exceptions, don't bury them.
btw - yes, i have been that guy that has to figure out these types of mistakes.
It seems like you need to read about mvc3 and entity framework before writing coding and asking in here for help on something that's coded full of bad practices.
Answering your questions:
1- no
2- makes no sense as the answer to 1
Do it right, here are some useful documentation: http://msdn.microsoft.com/en-us/library/ie/gg416514(v=vs.98).aspx
EDIT: Adding some explicit fix
You could access your dbcontext from an static class, something like this:
var context = DbProvider.CurrentDb;
The idea is to access your db from here always: from your extension methods and from your controller actions.
Then, the implementation of the DbProvider.CurrentDb will be something like this:
public static classDbProvider {
public static void Initialize(){
HttpContext.Current.ApplicationInstance.BeginRequest += CreateDb;
HttpConetxt.Current.ApplicationInstance.EndRequest += DisposeDb;
}
private static void CreateDb(object sender, EventArgs e) {
HttpContext.Items.Add("CurrentDb", new PbaDbEntities(););
}
private static void DisposeDb(object sender, EventArgs e)
{
Current.Dispose();
HttpContext.Items.Remove("CurrentDb");
}
public static PbaDbEntities CurrentDb{
get {
return (PbaDbEntities)HttpContext.Current.Items["CurrentDb"];
}
}
}
As you can see, it will create a new Db per each request and it will be available ONLY in that request. In that way, your db will be disposed at the end of each request. This pattern is called Open-Session-in-View.
Finally, you need to initialize the DbProvider calling the method
Initialize() in your Global.asax file, in the event Application_start.
Hope it helps.
I don't have any idea of the context here-- if db is simply a connection-like object or not, but it appears you are throwing away and recreating whatever it is unnecessarily.
Best to create a property (for whatever your doing) so to be consistent.
private static Thing _thing;
private static Thing thing{
get{
if(_thing==null){
_thing=new Thing();
}
return _thing;
}
}

Separating Logging Code from C# Objects

Currently I have a custom built static logging class in C# that can be called with the following code:
EventLogger.Log(EventLogger.EventType.Application, string.Format("AddData request from {0}", ipAddress));
When this is called it simply writes to a defined log file specified in a configuration file.
However, being that I have to log many, many events, my code is starting to become hard to read because all of the logging messages.
Is there an established way to more or less separate logging code from objects and methods in a C# class so code doesn't become unruly?
Thank you all in advance for your help as this is something I have been struggling with lately.
I like the AOP Features, that PostSharp offers. In my opinion Loggin is an aspect of any kind of software. Logging isn't the main value an application should provide.
So in my case, PostSharp always was fine. Spring.NET has also an AOP module which could be used to achieve this.
The most commonly used technique I have seen employs AOP in one form or another.
PostSharp is one product that does IL weaving as a form of AOP, though not the only way to do AOP in .NET.
A solution to this is to use Aspect-oriented programming in which you can separate these concerns. This is a pretty complex/invasive change though, so I'm not sure if it's feasible in your situation.
I used to have a custom built logger but recently changed to TracerX. This provides a simple way to instrument the code with different levels of severity. Loggers can be created with names closely related to the class etc that you are working with
It has a separate Viewer with a lot of filtering capabilities including logger, severity and so on.
http://tracerx.codeplex.com/
There is an article on it here: http://www.codeproject.com/KB/dotnet/TracerX.aspx
If your primary goal is to log function entry/exit points and occasional information in between, I've had good results with an Disposable logging object where the constructor traces the function entry, and Dispose() traces the exit. This allows calling code to simply wrap each method's code inside a single using statement. Methods are also provided for arbitrary logs in between. Here is a complete C# ETW event tracing class along with a function entry/exit wrapper:
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace MyExample
{
// This class traces function entry/exit
// Constructor is used to automatically log function entry.
// Dispose is used to automatically log function exit.
// use "using(FnTraceWrap x = new FnTraceWrap()){ function code }" pattern for function entry/exit tracing
public class FnTraceWrap : IDisposable
{
string methodName;
string className;
private bool _disposed = false;
public FnTraceWrap()
{
StackFrame frame;
MethodBase method;
frame = new StackFrame(1);
method = frame.GetMethod();
this.methodName = method.Name;
this.className = method.DeclaringType.Name;
MyEventSourceClass.Log.TraceEnter(this.className, this.methodName);
}
public void TraceMessage(string format, params object[] args)
{
string message = String.Format(format, args);
MyEventSourceClass.Log.TraceMessage(message);
}
public void Dispose()
{
if (!this._disposed)
{
this._disposed = true;
MyEventSourceClass.Log.TraceExit(this.className, this.methodName);
}
}
}
[EventSource(Name = "MyEventSource")]
sealed class MyEventSourceClass : EventSource
{
// Global singleton instance
public static MyEventSourceClass Log = new MyEventSourceClass();
private MyEventSourceClass()
{
}
[Event(1, Opcode = EventOpcode.Info, Level = EventLevel.Informational)]
public void TraceMessage(string message)
{
WriteEvent(1, message);
}
[Event(2, Message = "{0}({1}) - {2}: {3}", Opcode = EventOpcode.Info, Level = EventLevel.Informational)]
public void TraceCodeLine([CallerFilePath] string filePath = "",
[CallerLineNumber] int line = 0,
[CallerMemberName] string memberName = "", string message = "")
{
WriteEvent(2, filePath, line, memberName, message);
}
// Function-level entry and exit tracing
[Event(3, Message = "Entering {0}.{1}", Opcode = EventOpcode.Start, Level = EventLevel.Informational)]
public void TraceEnter(string className, string methodName)
{
WriteEvent(3, className, methodName);
}
[Event(4, Message = "Exiting {0}.{1}", Opcode = EventOpcode.Stop, Level = EventLevel.Informational)]
public void TraceExit(string className, string methodName)
{
WriteEvent(4, className, methodName);
}
}
}
Code that uses it will look something like this:
public void DoWork(string foo)
{
using (FnTraceWrap fnTrace = new FnTraceWrap())
{
fnTrace.TraceMessage("Doing work on {0}.", foo);
/*
code ...
*/
}
}
To make the code readable, only log what you really need to (info/warning/error). Log debug messages during development, but remove most when you are finished. For trace logging, use
AOP to log simple things like method entry/exit (if you feel you need that kind of granularity).
Example:
public int SomeMethod(int arg)
{
Log.Trace("SomeClass.SomeMethod({0}), entering",arg); // A
if (arg < 0)
{
arg = -arg;
Log.Warn("Negative arg {0} was corrected", arg); // B
}
Log.Trace("SomeClass.SomeMethod({0}), returning.",arg); // C
return 2*arg;
}
In this example, the only necessary log statement is B. The log statements A and C are boilerplate, logging that you can leave to PostSharp to insert for you instead.
Also: in your example you can see that there is some form of "Action X invoked by Y", which suggests that a lot of your code could in fact be moved up to a higher level (e.g. Command/Filter).
Your proliferation of logging statements could be telling you something: that some form of design pattern could be used, which could also centralize a lot of the logging.
void DoSomething(Command command, User user)
{
Log.Info("Command {0} invoked by {1}", command, user);
command.Process(user);
}
I think it is a good option to implement something similar to filters in ASP.NET MVC. This is implement with the help of attributes and reflection. You mark every method you want to log in a certain way and enjoy. I suppose there might be a better way to do it, may be with the help of Observer pattern or something but as long as I thought about it I couldn't think of something better.
Basically such problems are called cross-cutting concerns and can be tackled with the help of AOP.
I also think that some interesting inheritance schema can be applied with log entities at the base but I would go for filters

C# Delegates & guid.newguid()

I just started using C# this afternoon, so be a little gentle.
Currently I am working on a type of "template engine" where one of the callbacks needs to generate a globally unique ID. I am using delegates to manage the callbacks.
Currently the code looks like this (though I have also tried an anonymous function & returning NewGuid directly w/o a variable):
static string UID(List<string> p)
{
string s = Guid.NewGuid().ToString();
return s;
}
Which, when called directly, works fine. However if I try to call it via the delegate (added to a StringDictionary via addCallback("generate UID", new CallbackWrapper(UID))), the program will generate the same GUID regardless of how many times I duplicate it; even though calling the method directly both before & after the event occurs results in a unique ID as expected. I'v
No doubt it's just something simple I've missed, inevitably stemming from me being relatively inexperienced at C#.
Any help would be appreciated.
Thanks.
Well, I've now tried Dictionary with the same result.
CallbackWrapper is just the delegate, it's defined like this:
delegate string CallbackWrapper(List<string> parameters);
The remainder of the work is done in another class, which looks like this:
class TemplateParser
{
private Dictionary<string, CallbackWrapper> callbackMap;
public TemplateParser(string directivePrefix, string directiveSuffix)
{
...
callbackMap = new Dictionary<string,CallbackWrapper>();
}
public TemplateParser() : this("<!-- {", "} -->") {}
{
callbackMap.Add(name, callback);
}
public string parse(string filename)
{
...
string replacement =
callbackMap[directiveName](new List<string>(parameters.Split(new string[] { ";", " " }, StringSplitOptions.RemoveEmptyEntries));
...
}
}
I've stripped out the majority of the string handling code to save some space.
The issue is in your calling code, not in the code itself, nor in the delegate.
Using delegates here definitely works if called correctly.
Furthermore, your code can be slightly simplified:
static string UID(List<string> p)
{
return Guid.NewGuid().ToString();
}
(The variable is utterly redundant.)
use delegate.invoke
The difference between direct function call and delegate.invoke is here
http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/f629c34d-6523-433a-90b3-bb5d445c5587
StringDictionary will automatically cast your CallbackWrapper to a string, meaning it will only run once and store the output of CallbackWrapper.ToString(). This is probably not what you want.
Try using Dictionary<string, CallbackWrapper> instead.

Categories