我想知道在我的域对象上直接使用log4net是不好的做法......我将在ASP.NET MVC应用程序端使用ELMAH作为我的异常,但出于某些参考目的,我想要记录有关域模型本身的一些数据。
给出以下域对象:
public class Buyer
{
private int _ID;
public int ID
{
get { return _ID; }
set
{
_ID = value;
}
}
private IList<SupportTicket> _SupportTickets=new List<SupportTicket>();
public IList<SupportTicket> SupportTickets
{
get
{
return _SupportTickets.ToList<SupportTicket>().AsReadOnly();
}
}
public void AddSupportTicket(SupportTicket ticket)
{
if (!SupportTickets.Contains(ticket))
{
_SupportTickets.Add(ticket);
}
}
}
在AddSupportTicketMethod中添加日志记录行为是一个坏主意......所以很重要,它看起来像这样:
public class Buyer
{
protected static readonly ILog log = LogManager.GetLogger(typeof(SupportTicket));
public Buyer()
{
log4net.Config.XmlConfigurator.Configure();
}
private int _ID;
public int ID
{
get { return _ID; }
set
{
_ID = value;
}
}
private IList<SupportTicket> _SupportTickets=new List<SupportTicket>();
public IList<SupportTicket> SupportTickets
{
get
{
return _SupportTickets.ToList<SupportTicket>().AsReadOnly();
}
}
public void AddSupportTicket(SupportTicket ticket)
{
if (!SupportTickets.Contains(ticket))
{
_SupportTickets.Add(ticket);
} else {
log.Warn("Duplicate Ticket Not Added.");
}
}
}
答案 0 :(得分:3)
我在域对象中直接使用了log4net和log4J。这有很好的副作用和不好的副作用。
在域对象中不记录是一个坏主意。替代方案正如其他人所建议的那样,依赖注入或外部框架(例如log4J的commons-logging)允许插入不同的日志框架或创建一个对该接口进行日志记录和日志记录的接口。 (使用您的域对象的代码然后需要提供该接口的适当实例以用于记录目的。)
答案 1 :(得分:1)
这是一个经典问题!
这样做的好方法是引入ILogger类的类成员并将日志记录抽象到此接口中。在你的班级中,无论你做什么,都要通过这个界面调用logg。然后在运行时使用其中一个可用的IoC容器或依赖注入farmeworks注入此依赖项。默认情况下,您可以使用此接口的log4net实现。
以下是一长串可用的依赖注入框架: http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx
答案 2 :(得分:1)
如果您要从您的域对象登录并使用您可能想要换出的IOC容器,我建议您使用服务定位器模式(您可以查看Sharp#architecture以获得一个很好的实现一个SafeServiceLocator,包含msoft的ServiceLocator,提供更多信息性错误消息)。
我还建议您考虑是否要记录您在示例中显示的错误类型。在这种情况下,我倾向于让域对象抛出一个异常,并让调用者决定这是否是应用程序所期望的(因此不应该被记录)或者是否代表调用者想要的情况以某种方式处理。
答案 3 :(得分:0)
我认为日志记录是一个跨领域的问题,因此最好以面向方面的方式完成。如果您使用的是Spring.NET这样的框架,那么您可以使用它。