2009-04-23 56 views
2

我想知道是否在我的域對象上直接使用log4net是不好的做法......我將在ASP.NET MVC應用程序端使用ELMAH作爲例外,但出於一些信息的目的,我想記錄有關域模型本身的一些數據。我應該直接在我的域模型對象中使用log4net嗎?

鑑於以下域對象:

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添加日誌的行爲是一個壞主意...所以essentialy它會是這樣的:

 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."); 
     } 
    } 
} 

回答

1

如果你打算從你的域對象登錄,並且你使用了一個你可能想要換出的IOC容器,我會建議你使用Service Locator模式(你可以看看Sharp#架構的一個很好的SafeServiceLocator實現,它包含了msoft的ServiceLocator和更多信息錯誤消息)。

我還想建議您考慮是否要記錄您在示例中顯示的錯誤類型。我傾向於希望在這種情況下讓域對象拋出異常,並讓調用者決定這是否是應用程序期望的東西(因此不應該被記錄)或者是否表示調用者想要的情況以某種方式處理。

+3

服務定位器是一種反模式,並且破壞了依賴注入的目的。這個答案不是主觀錯誤的,它是客觀錯誤的。 – jason 2011-02-13 17:18:57

1

這是一個經典題!

這樣做的好方法是引入一個ILogger類型的類成員並將日誌記錄抽象到此接口中。在你的課上,無論你做什麼,都可以通過這個界面進行調用。然後使用可用的IoC容器或依賴注入farmeworks之一在運行時注入此依賴項。默認情況下,你可以使用這個接口的log4net實現。

這裏是可用的依賴注入框架的一個長長的清單: http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx

0

我想記錄是一個橫切關注點,所以最好在面向方面的方式進行。如果您使用的是像Spring.NET這樣的框架,那麼您可以使用它。

3

我在域對象中直接使用了log4net和log4J。這有很好的副作用和壞的。

  • +:登錄域對象是簡單明瞭的代碼,你知道你可以採取的log4net的功能。
  • -:這意味着該程序利用域對象的需要注意的log4net的配置,這可能會或可能不會是一個問題
  • -:你不能域對象鏈接到不同於調用程序正在使用的log4net版本。我看到很多與log4net 1.2.0.10鏈接的項目和另一個與早期版本鏈接的項目有衝突。

不記錄在你的域對象是一個壞主意。另一種方法就像其他人所說的那樣,依賴注入或外部框架(例如log4J的commons-logging)允許插入不同的日誌框架或創建一個接口來執行日誌記錄和針對該接口的日誌記錄。 (使用你的域對象的代碼將需要爲記錄目的提供該接口的適當實例。)