我有一个简单的winform测试应用程序,我正在尝试使用Log4Net依赖注入的东西。
我在 Services 项目中创建了一个简单的界面: -
public interface ILogging
{
void Debug(string message);
// snip the other's.
}
然后我的具体类型将使用Log4Net ......
public class Log4NetLogging : ILogging
{
private static ILog Log4Net
{
get { return LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); }
}
public void Debug(string message)
{
if (Log4Net.IsDebugEnabled)
{
Log4Net.Debug(message);
}
}
}
到目前为止一切顺利。那里没什么难的。
现在,在一个不同的项目(以及因此的名称)中,我尝试使用它......
public partial class Form1 : Form
{
public Form1()
{
FileInfo fileInfo = new FileInfo("Log4Net.config");
log4net.Config.XmlConfigurator.Configure(fileInfo);
}
private void Foo()
{
// This would be handled with DI, but i've not set it up
// (on the constructor, in this code example).
ILogging logging = new Log4NetLogging();
logging.Debug("Test message");
}
}
好的..也很简单。我已经对ILogging实例进行了硬编码,但这通常是通过构造函数注入的依赖项。无论如何,当我检查这行代码时......
return LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
DeclaringType
类型值是 Service 命名空间,而不是实际调用该方法的 Form (即X.Y.Z.Form1)的类型。
如果不将类型INTO方法作为另一个参数传递,是否仍然使用反射来找出调用它的real
方法?
答案 0 :(得分:1)
可能有助于某人的额外答案 根据Steve的建议,我改变了我的日志服务实现,使其具有一个接受一个类型的构造函数,即提供的类型参数 ILogger接口中指定的Log方法
public class MyLogging_Service : IMyLogging_Service
{
private Type _declaringType;
private ILog _log;
private ILog Log { get { return _log; } }
public MyLogging_Service(Type p_Val)
{
_declaringType = p_Val;
_log = LogManager.GetLogger(p_Val);
}
public void LogInfo(string p_Msg)
{
Log.Logger.Log(_declaringType, Level.Info, p_Msg, null);
}
...
}
实际使用
public class Service1 : IService1
{
// declared as a property
IMyLogging_Service MyLoggingService { get; set; }
}
之前我使用StructureMap自动填充此属性
二传手注射
见link
在我的依赖注入引导程序中,我使用了以下语句
FillAllPropertiesOfType<IMyLogging_Service>().TheDefault.Is
.ConstructedBy(context => new MyLogging_Service(context.ParentType));
回顾一下
1。创建了一个类,使用构造函数实现日志记录,该构造函数接受一个类型,用于在Log方法实现中指定callerStackBoundaryDeclaringType参数
2。为需要具有日志记录功能的类创建了日志服务属性
3。在依赖注入引导程序中包含代码,使用上下文StructureMap变量
btw在您的代码中没有必要DI的情况下,您可以编写这样的代码
new MyLogging_Service(this.GetType())
答案 1 :(得分:0)
要获取调用特定方法的MethodInfo
对象,需要检查调用堆栈。这可以通过StackTrace
类以下列方式完成。
using System.Diagnostics;
using System.Reflection;
public class Log4NetLogging : ILogging
{
private ILog GetLogForStackFrame(StackFrame frame)
{
return LogManager.GetLogger(frame.GetMethod().DeclaringType);
}
public void Debug(string message)
{
ILog log = GetLogForStackFrame(new StackTrace().GetFrame(0));
if (log.IsDebugEnabled)
{
log.Debug(message);
}
}
}
在旁注中,我会考虑修改您的接口以接受将使用抽象日志的对象的Type
。我意识到你不想这样做,但是在运行时检索调用堆栈是一项代价高昂的操作,每次调用ILogging.Debug
时都需要执行。