2009-09-01 4 views
2

J'essaie de trouver la meilleure méthode pour effectuer la journalisation dans l'application que je suis en train de développer.Exécution des opérations de journalisation dans MVC .NET

maintenant, j'ai une table de journal qui stocke le nom d'utilisateur, l'horodatage, l'action, le contrôleur et un message. Lorsqu'un contrôleur est instancié, il reçoit l'information de l'IoC via Castle Windsor.

par exemple, mon contrôleur « Sites » est créé comme suit:

private ISitesRepository siteRepository; 
    private ILogWriter logWriter; 

    public SiteController(ISitesRepository siteRepository, ILogWriter logWriter) 
    { 
     this.siteRepository = siteRepository; 
     this.logWriter = logWriter; 
    } 

et l'auteur du journal a une fonction qui crée et insère une entrée de journal (WriteToLog). Dans les actions Edit et Create du contrôleur de site, il appelle la fonction WriteToLog.

cela fonctionne et fait son travail, mais ma question est - ai-je vraiment besoin de configurer chaque contrôleur de cette façon, en passant par l'interface/référentiel ILogWriter? Il m'a semblé que je pourrais peut-être mettre en place un LogController, et avoir juste cela faire le "lourd" de l'écriture de mes journaux. De cette façon, je n'aurais pas à jouer avec les trucs IoC dans tous les autres contrôleurs. est-il possible d'exécuter une action sur un autre contrôleur (par exemple, un LogController-> WriteLog)? Je ne sais pas comment cela se ferait sans faire de redirection ...

Répondre

1

Ok, après avoir gratté beaucoup la tête, je pense que je l'ai trouvé une solution acceptable.

Je mis en œuvre mon action de l'exploitation forestière comme un filtre d'action personnalisé comme si:

public class LogAction : ActionFilterAttribute, IActionFilter 
{ 
    public LogLevel loglevel; 
    public string message; 


    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     ILogWriter logWriter = AppServiceFactory.Instance.Create<ILogWriter>(); 

     logWriter.WriteToLog(
      filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, 
      filterContext.ActionDescriptor.ActionName, 
      loglevel, 
      filterContext.HttpContext.Timestamp, 
      filterContext.HttpContext.User.Identity.Name.ToString(), 
      message + "(id=" + filterContext.RouteData.Values["id"] + ")"); 
    } 

} 

mais je suis tombé sur un mur en essayant d'obtenir le filtre attribut IoC à travailler dans une coutume. J'ai trouvé que c'était plutôt difficile à faire, en parlant de l'utilisation de wrappers différents, d'invocateurs d'action, etc., ce qui semblait plus compliqué que ce que je voulais vraiment faire. En essayant d'en savoir plus sur IoC (je suis encore très nouveau à ce sujet), j'ai trouvé this article, qui m'a vraiment aidé à pointer dans la bonne direction. J'ai ajouté sa classe scellée AppServiceFactory avec mon WindsorControllerFactory, et cela a fonctionné comme un charme. Comme je l'ai dit, je suis très nouveau avec MVC et ces choses IoC, donc je ne suis pas sûr que ce soit un moyen idéal de gérer les choses, mais il semble simple et cela fonctionne jusqu'à présent. Je serais heureux de recevoir des commentaires ou des critiques sur le traitement de cette méthode.

MISE À JOUR cernées une autre façon de faire this- a créé une fonction dans mon projet WebUI en tant que tel:

public static class Loggers 
{ 
    public static void WriteLog(ControllerContext controllerContext, LogLevel logLevel, string message) 
    { 
     ILogWriter logWriter = AppServiceFactory.Instance.Create<ILogWriter>(); 
     logWriter.WriteToLog(
      controllerContext.RouteData.Values["controller"].ToString(), 
      controllerContext.RouteData.Values["action"].ToString(), 
      logLevel, 
      controllerContext.HttpContext.Timestamp, 
      controllerContext.HttpContext.User.Identity.Name.ToString(), 
      message); 
    } 
} 

maintenant, chaque fois que je veux connecter quelque chose, je peux appeler

  Loggers.WriteLog(
      this.ControllerContext, 
      LogLevel.Membership, 
      "Removed role '" + role + "'" + " from user " + _userService.Get(id).UserName); 

pour écrire un enregistrement dans le journal. cela me donne beaucoup plus de flexibilité sur mon contenu "message", et résout le problème d'inclure la journalisation dans le global.fichier asax, ce qui aurait été difficile, voire impossible, en utilisant les filtres d'attributs. Je vais laisser le reste, car il peut être utile à quelqu'un d'autre, mais je pense que c'est la façon dont je vais y aller.

comme d'habitude, les choses sont généralement plus simples dans MVC que je pense d'origine, ils seront :)

+0

un comment- la seule chose que je n'aime pas à ce sujet est que je ne peux pas personnaliser le champ « message » avec des données qui ne peuvent être trouvées que dans l'action qui provoque le déclenchement du filtre. travaillera sur ceci. –

1

Pourriez-vous passer par un cours abstrait? Cette classe abstraite ayant une propriété statique référençant vous écrivain journal?

quelque chose comme ça

public abstract class BaseController 
{ 
    public static ILogWriter Logwriter{get;set;} 
    public static BaseController 
    { 
     Logwriter = YourFactory.GetLogwriter(); 
    } 
} 

public class YourController:BaseController 
{ 
    public YourController(ISitesRepository siteRepository) 
    { 
    } 
} 
Questions connexes