2009-04-23 5 views
2

Je me demande si c'est une mauvaise pratique d'utiliser log4net directement sur mon objet de domaine ... J'utiliserai ELMAH pour mes exceptions sur le côté de l'application ASP.NET MVC, mais à des fins d'information j'aimerais m'enregistrer certaines données sur le modèle de domaine lui-même.Dois-je utiliser log4net directement dans mes objets de modèle de domaine?

Compte tenu de l'objet de domaine suivant:

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

ajoute le comportement de l'exploitation forestière dans la AddSupportTicketMethod une mauvaise idée ... si essentialy qu'il avait ressembler à ceci:

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

Répondre

1

Si vous souhaitez vous connecter à partir de vos objets de domaine et utiliser un conteneur IOC que vous souhaitez échanger , Je vous recommande d'utiliser le modèle Service Locator (vous pouvez regarder l'architecture Sharp # pour une implémentation agréable d'un SafeServiceLocator qui enveloppe le ServiceLocator de msoft avec des messages d'erreur plus informatifs).

Je voudrais également suggérer que vous considériez si vous voulez enregistrer le type d'erreur que vous montrez dans votre exemple.J'aurais tendance à vouloir que l'objet domain jette une exception dans ce cas et laisse l'appelant décider si c'était quelque chose qui était attendu par l'application (et donc ne devrait pas être connecté) ou si cela représente une situation que l'appelant veut traiter d'une certaine manière.

+3

Le localisateur de service est un anti-pattern, et annule le but de l'injection de dépendance. Cette réponse n'est pas subjectivement erronée, elle est objectivement fausse. – jason

+0

Je suis d'accord avec Jason. Plus d'infos: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx – autonomatt

1

C'est un classique question!

La bonne méthode consiste à introduire un membre de classe de type ILogger et de résumer la consignation dans cette interface. Dans votre classe, partout où vous appelez pour vous connecter, faites-le via cette interface. Injectez ensuite cette dépendance à l'exécution avec l'une des implémentations en utilisant l'un des conteneurs IoC disponibles ou l'injection de dépendance farmeworks. Par défaut, vous pouvez utiliser l'implémentation log4net de cette interface.

Voici une liste des cadres d'injection de dépendance disponibles: http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx

0

Je pense que l'exploitation forestière est une préoccupation transversale, il est donc préférable de faire de façon orientée aspect. Si vous utilisez un framework comme Spring.NET, il est disponible pour vous.

3

J'ai utilisé log4net et log4J directement dans les objets de domaine. Cela a de bons effets secondaires et mauvais.

  • +: Exploitation forestière dans l'objet de domaine est simple et facile à code et vous savez que vous pouvez tirer parti des fonctionnalités de log4net.
  • -: Cela signifie que le programme utilisant des objets de domaine doit prêter attention à la configuration log4net, qui peut ou peut ne pas être un problème
  • -: Vous ne pouvez pas lier votre objet de domaine à un version log4net différente de celle utilisée par le programme appelant. J'ai vu beaucoup de conflits avec un élément lié à log4net 1.2.0.10 et un autre lié à une version antérieure.

Ne pas se connecter dans votre objet de domaine est une mauvaise idée. L'alternative est, comme d'autres l'ont suggéré, l'injection de dépendances ou un framework externe (tel que log-logging pour log4J) qui permet de brancher différents frameworks de logs ou de créer une interface qui fait la journalisation et la journalisation sur cette interface. (Le code utilisant votre objet domaine devra alors fournir une instance appropriée de cette interface à des fins de journalisation.)

Questions connexes