Tech Off Thread

2 posts

The Log VS Coupling problem. How can I use DI in these example?

Back to Forum: Tech Off
  • User profile image
    vitorrubio

    I'm doing an asp.net system using nHibernate for persistence.
    In my code I'm separating the business classes/objects from repository. I have a set of repository classes with internally use nhibernate, but this is transparent to my application.
    I have a need to log every CRUD operation in my repository, so I created a log class and a log repository, but all repositories need to have two things in order to work properly with the log:
    1) An instance of the user class, to register who is the user that perfomed the crud operation
    2) An instance of the HTTPContext object, to get some information about session, server and browser.

    I know it is the wrong way to do this, but I dont know the best way. If I put log logic in the base repository class I have the repository coupled with HTTPSession and can't use my business objects in a windows form application.
    If I do log logic outside repository I need to do this in the application layer, and maybe replicate log-related code throgh my application.

    Besides, how can I "inject" the user and session information in my repository class? I am doing this on the constructor.

    Below follows an example of my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using LiderTel.Modelo;

    namespace LiderTel.Persistencia
    {
    public class BaseRepositorio<T> where T: Entity
    {
    private Sessao _sessaoInjetadaRepositorio;
    private Usuario _usuarIoinjetadoRepositorio;

    protected virtual Sessao GetSession()
    {
    return _sessaoInjetadaRepositorio;
    }

    protected virtual Usuario GetUser()
    {
    return _usuarIoinjetadoRepositorio;
    }

    public BaseRepositorio(Sessao sess, Usuario usu)
    {
    _sessaoInjetadaRepositorio = sess;
    _usuarIoinjetadoRepositorio = usu;
    }

    public BaseRepositorio(Sessao sess)
    : this(sess, sess==null?null:sess.UsuarioCriador)
    {

    }

    public BaseRepositorio()
    : this(SessionServices.GetSessaoCorrente(), SessionServices.GetSessaoCorrente()==null?null:SessionServices.GetSessaoCorrente().UsuarioCriador)
    {

    }


    private string GetUserID()
    {
    return (GetUser() != null) ? GetUser().ID.ToString() : "";
    }

    public virtual void Add(T ent)
    {
    ent.Criacao = DateTime.Now;
    ent.UsuarioCriador = GetUser();
    ent.Excluido = false;
    ent.Ativo = true;
    NHibernateHelper.GetDefaultSession().Save(ent);

     

    Log log = new Log();
    log.Acao = string.Format("{0} {1} created by {2}.", ent.GetType().Name, ent.ID.ToString(), GetUserID());
    log.TipoEvento = TipoEventoLog.Inclusao;
    log.Entidade = ent.ID;
    if (GetSession() != null)
    {
    log.SessaoID = GetSession().ID;
    }
    log.ComoEstava = ent.InternalToString();

    LogRepository logrep = new LogRepository(GetSession(), GetUser());
    logrep.Add(log);
    }
    }
    }

  • User profile image
    wkempf

    Several possible solutions. The easiest is to inject a factory for the log service, rather than the log service itself. The class can then use the factory to create the specific instance it needs by passing the user and HTTPContext to the factory method.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.