Reputation: 3166
I'm building a class project (seperate dll) that will contain various helper methods and common functionality, to be accessed by a range of different applications - an ASP.NET website, a web service and a Windows service.
Is there any way that this neutral class can determine the type of application that is calling it (so it could, for example, make a choice about how to log information)?
What other 'meta'-information is available to a class about what application is calling it?
Upvotes: 3
Views: 161
Reputation:
Your design. There is something wrong with it.
Factor out these "If its a X do it Y, if its an A do it B" choices by using dependency injection. Those behaviors that change in different contexts should be encapsulated into objects that implement a common interface. The caller will determine what implementation of an interface he wants you to use and injects it into your instance before calling your methods.
Upvotes: 0
Reputation: 7825
Although I completely agree with the answers here so far, you can get reflection information about the loaded modules, combining this with a stack trace, you can figure out the function and class that is calling your code and get the reflection info for that.
But, to reiterate, I agree with the other posts in that you should abstract this through an interface, as this makes it clear to other programmers how data will be used and reduces the chances of bugs being introduced due to a miss-understanding. (IMHO, reflection should really only be used for things like serialization and explicit operations directly controlled by attributes, such as the GUI editor in .Net)
Upvotes: 0
Reputation: 10247
You could get the information by looking at the stack trace:
StackTrace stackTrace = new StackTrace(); // Get call stack
StackFrame[] stackFrames = stackTrace.GetFrames(); // Get method calls (frames)
string methodName = stackFrames[0].GetMethod().Name; // Get method name
string type = stackFrames[0].GetType().ToString(); // Get the calling type
However, I think the better solution would be to use a more object-oriented approach. Create different loggers that implement the same interface. Pass an instance of your logger to the class depending on what is creating and using the class.
public interface ILogger
{
void Log(string message);
}
public class MyWorkerClass
{
private ILogger m_Logger;
public MyWorkerClass(ILogger logger)
{
m_Logger = logger;
}
public void Work()
{
m_Logger.Log("working")
}
// add other members...
}
public class MyService
{
public void DoSomething()
{
ILogger logger = new MyServiceLogger();
MyWorkerClass worker = new MyWorkerClass(logger);
worker.Work();
}
}
Upvotes: 5
Reputation: 12971
If you use a logging framework, such as NLog or Log4Net, the way you log things is configured in your client application. In your shared library, you'll just use a logger, without having to take care of the way log entries will be saved (files, event log, mail, etc.).
Upvotes: 0
Reputation: 73311
A class should have no knowledge about how it is being used. Remember it is a black box.
If you want to expose logging to a class, create a logging interface, that is passed to the class, in a constructor or a method.
Then each calling application can implement its own version of the logger, and the logging implementation can have the detail you are looking for. And the class will only use the interface for example to LogMessage, LogError, etc. . .
Upvotes: 9