Linq to Sql Context único por aplicação

by Cássio R Eskelsen 14. setembro 2008 14:04

Otávio P. Coelho escreveu recentemente um post sugerindo o uso de singletons para manter o contexto de um Entity Data Model.

Venho utilizando essa estratégia há um bom tempo já  para minhas aplicações que usam Linq to SQL e a partir do post do Otávio resolvi compartilhar um trecho de código que pode ser usado por todos.

Qual a vantagem de criar um singleton para isso? Bom, imagine que uma determinada rotina do seu código precise “atravessar”  por vários métodos de instâncias de várias classes e imagine que essa “travessia” precise estar coberta por uma transação. Você não pode então criar uma instância do seu data context em cada método e passar um context já criado e passar como parâmetro é uma solução muito “feia” além  de não permitir a separação das suas regras de negócio da camada de persistência.

Com um singleton, os métodos passam a “buscar” um data context já aberto, ou, se ainda não estiver criado, instancia um novo.

Usando os métodos CallContext e SetContext podemos manter o data context no contexto da aplicação, o que significa que em aplicações Windows Forms ele estará válido durante toda a execução do programa, ou no caso de aplicações WEB, durante o ciclo de vida de uma chamada Http Request.

Essa solução é transparente para aplicações WEB e Desktop, ou seja, se sua camada de negócios e/ou sua camada de persistência são usadas simultaneamente nas duas plataformas, a solução não precisa ser “ajustada”.

Exemplo abaixo, DataRepository é o nome do meu Data Context. Substitua pelo seu.

using System.Runtime.Remoting.Messaging;

namespace LINQToSQL
{
    public class Helper
    {
        #region Privates

        private static string _stringConexao = null;

        private const string DATACONTEXT_ITEMS_KEY = "DBHelperContextKey";

        private static DataRepository DataBaseContext
        {
            get
            {
                return (DataRepository)CallContext.GetData(DATACONTEXT_ITEMS_KEY);
            }
            set
            {
                CallContext.SetData(DATACONTEXT_ITEMS_KEY, value);
            }
        }

        #endregion

        #region Public and Protected Properties and Methods

        /* a string de conexão você pode manter de várias formas
         * talvez a mais prática seja recuperar diretamente via ConfigurationManager
         */
        public static string StringConexao
        {
            get
            {
                return _stringConexao;
            }
            set
            {
                if (_stringConexao != null && _stringConexao.Equals(value))
                    return;

                //Se já tem um DatabaseContext criado, elimina ele para
                //que na próxima chamada seja reaberto com a nova string
                //de conexao.
                if (DataBaseContext != null)
                {
                    CleanUp();
                }

                _stringConexao = value;
            }
        }

        public static DataRepository Db
        {
            get
            {
                if (DataBaseContext == null)
                {
                    DataBaseContext = new DataRepository(StringConexao);
                }

                return DataBaseContext;
            }
        }

        public static System.IO.TextWriter Log
        {
            get
            {
                return Db.Log;
            }
            set
            {
                Db.Log = value;
            }
        }

        public static void CleanUp()
        {
            if (DataBaseContext != null)
            {
                DataBaseContext.Dispose();
                DataBaseContext = null;
            }
        }

        #endregion
    }
}

Tags: , ,

.Net | Arquitetura

Comentários

Comentar




  Country flag

biuquote
  • Comentário
  • Pré-visualização
Loading