Arquitectura – Definición de un DataHelper, Parte 1

Hola ¿Qué tal?…


En esta ocasión continuando con la propuesta de arquitectura que comenté en el último artículo de arquitectura (http://msmvps.com/blogs/otelis/archive/2008/01/08/hablemos-de-arquitectura-de-software.aspx)  quiero comenzar por establecer primeramente las directrices basadas enteramente en el documento titulado “Application Architecture for .NET: Designing Applications and Services” (http://msdn2.microsoft.com/en-us/library/ms954595.aspx). En principio estaré enfocado al capítulo 2 de este documento para definir simplemente la base de esta propuesta.


Considerando que encontramos tres grandes grupos de componentes, divididos en Presentación, Negociación y Datos, quisiera empezar primeramente por la parte más baja, donde encontramos a los datos, para iniciar desde ahí. El por qué empezar desde este punto es por definición de donde continúa la construcción de una aplicación, donde primeramente se diseña la base de datos y en seguida se construye la aplicación.


De acuerdo a las recomendaciones, cada tabla de la base de datos debe corresponderse con un componente de acceso a datos, en mi percepción, genero un componente de acceso a datos por tabla siguiendo ciertos criterios que posteriormente mostraré. Inicialmente, debo definir un DataHelper, que será el encargado de establecer la conexión con la base de datos, y que será dónde la conexión se administre y viva, ahí se ejecutará cualquier acción dirigida a la base de datos, acciones como, consultas, modificaciones y hasta alteraciones a la estructura de la base de datos, así pues, debemos entender que la conexión con la base de datos solo estará en este componente, solo en el Helper y en ninguna otra parte. La definición en el modelo que propongo será sobre una clase abstracta y deberá ser heredada en cada componente de acceso a datos. El criterio para definirla abstracta, es porque no debe ser instanciada de forma directa, así los componentes de acceso a datos serán quienes tengan la capacidad de exponer la funcionalidad con la base de datos totalmente específica de cada uno de estos de un modo íntimo y discreto, exponiendo únicamente los métodos que le concierne a los componentes que los consuman.


Este Helper contará con el soporte de una interfaz cuya función será propagar la información necesaria para conectarse a la base de datos, esto es, la información básica de usuario, servidor, base de datos y contraseña, con esta interfaz podremos inicializar el helper y darle capacidad de interactuar con la base de datos. Esta información se propagará en el constructor de cada componente de acceso a datos que se derive del helper. Es importante mencionar que esta interfaz es la chispa de vida de cada componente de acceso a datos y que sin ella nada funcionará.


Entonces, teniendo en cuenta esto podemos empezar a definir la estructura de nuestro helper. Veamos entonces de una buena vez cómo definimos la clase de este componente.


VB


Namespace DataHelper


    Public MustInherit Class SqlDataHelper


        Public Sub New(ByVal sqlSet As DBInfo.IDbSettings)


 


        End Sub


    End Class


End Namespace


C#


namespace DataHelper


{


    public abstract class SqlDataHelper


    {


        public SqlDataHelper(DBInfo.IDbSettings sqlSet)


        {


 


        }


    }


}


 


La interfaz que sirve de apoyo al transporte de la información de conexión de la base de datos estaría definida de la siguiente manera:


VB


Namespace DBInfo


 


    Public Interface IDbSettings


        Property Server() As String


        Property DataBase() As String


        Property User() As String


        Property Password() As String


        Function GetConnectionString() As String


    End Interface


 


End Namespace


C#


namespace DBInfo


{   


    public interface IDbSettings


    {


        string Server{get;set;}


        string DataBase{get;set;}


        string User{get;set;}


        string Password{get;set;}


        string GetConnectionString();


    }


}


Nótese que se tienen dos espacios de nombre, el primero totalmente relacionado al DataHelper y el segundo relacionado a información de la Base de Datos, he decidido dejarlos separados para no mezclar conceptos.


Ahora bien, ya definimos la clase y la interfaz de información de conexión, sin embargo, habrá todavía más que hacer, empezaré terminando con la definición básica del DataHelper, el cual es alusivo a SQL Server; por cierto.


Lo siguiente será definir la funcionalidad del constructor, y declarar la variable de conexión con la que se trabajará en las operaciones relacionadas con el mismo apuntando a una base de datos.


Inicialmente debemos declarar una variable del tipo SqlConnection, para utilizarla en todo el helper, utilizaremos varias variables adicionales para devolver los mensajes que se generen dentro de cada método del helper, además de los mensajes nativos del servidor y los números de error en caso de que se presenten y por si fuera poco, también una variable que indique si la conexión es buena o no y una variable para almacenar la información de conexión para tenerla disponible en todo momento dentro del helper. Así pues tendremos las siguientes declaraciones iníciales:


VB


Public MustInherit Class SqlDataHelper


    Private cnnHelper As SqlConnection


    Private mMessageHelper As String


    Private mMessageServer As String


    Private mErrorNumber As Integer


    Private mIsValidConnection As Boolean


    Private mSqlSettings As IDbSettings


 


    Public Sub New(ByVal sqlSet As DBInfo.IDbSettings)


 


    End Sub


End Class


C#


public abstract class SqlDataHelper


{


    private SqlConnection cnnHelper;


    private string messageHelper;


    private string messageServer;


    private int errorNumber;


    private bool isValidConnection;


    private IDbSettings sqlSettings;


 


    public SqlDataHelper(DBInfo.IDbSettings sqlSet)


    {


    }


}


Continuando con el constructor, instanciaremos la variable de conexión, además deberemos verificar que la conexión es válida para no caer en errores de conexión al intentar utilizar algún método de nuestro helper, por lo que definiremos un método para esta tarea. Al verificar la valides de la conexión podremos agregar un manejador para el evento que devuelve información del servidor cada que se utiliza la conexión. Este evento es el denominado InfoMessage de la conexión. No nos olvidemos del método manejador del evento InfoMessage de la conexión. Quedando la clase de esta manera:


VB


Public MustInherit Class SqlDataHelper


    Private cnnHelper As SqlConnection


    Private mMessageHelper As String


    Private mMessageServer As String


    Private mErrorNumber As Integer


    Private mIsValidConnection As Boolean


    Private mSqlSettings As IDbSettings


 


    Public Sub New(ByVal sqlSet As DBInfo.IDbSettings)


 


        mSqlSettings = sqlSet


        cnnHelper = New SqlConnection()


 


        If IsValidConnection() Then


            AddHandler cnnHelper.InfoMessage, _


            AddressOf cnnHelper_InfoMessage


        End If


 


    End Sub


 


    Private Sub cnnHelper_InfoMessage( _


            ByVal sender As Object, _


            ByVal e As SqlInfoMessageEventArgs)


 


        mMessageServer = e.Message


 


    End Sub


 


    Private Function IsValidConnection() As Boolean


 


        mErrorNumber = 0


        If cnnHelper.State = ConnectionState.Open Then


            cnnHelper.Close()


        End If


 


        cnnHelper.ConnectionString = mSqlSettings.GetConnectionString()


 


        Try


 


            If Not IsValidConnection Then


                cnnHelper.Open()


                cnnHelper.Close()


            End If


 


            mIsValidConnection = True


            mMessageHelper = “Conexión exitosa”


 


        Catch ex As SqlException


 


            mIsValidConnection = False


            mErrorNumber = ex.Number


            mMessageHelper = ex.Message


 


        End Try


 


        Return mIsValidConnection


 


    End Function


 


End Class


C#


public abstract class SqlDataHelper


{


    private SqlConnection cnnHelper;


    private string messageHelper;


    private string messageServer;


    private int errorNumber;


    private bool isValidConnection;


    private IDbSettings sqlSettings;


 


    public SqlDataHelper(DBInfo.IDbSettings sqlSet)


    {


        sqlSettings = sqlSet;


        cnnHelper = new SqlConnection();


 


        if (IsValidConnection())


        {


            cnnHelper.InfoMessage +=


                new SqlInfoMessageEventHandler(cnnHelper_InfoMessage);


        }


    }


 


    private void cnnHelper_InfoMessage(object sender, SqlInfoMessageEventArgs e)


    {


        messageServer = e.Message;


    }


 


    private bool IsValidConnection()


    {


        errorNumber = 0;


        if (cnnHelper.State == ConnectionState.Open)


            cnnHelper.Close();


 


        cnnHelper.ConnectionString = sqlSettings.GetConnectionString();


        try


        {


            if (!isValidConnection)


            {


                cnnHelper.Open();


                cnnHelper.Close();


            }


            isValidConnection = true;


            messageHelper = “Conexión exitosa”;


        }


        catch (SqlException ex)


        {


            isValidConnection = false;


            errorNumber = ex.Number;


            messageHelper = ex.Message;


        }


        return isValidConnection;


    }


}


Como podrá notarse el método manejador el evento InfoMessage es muy simple, solo tiene que pasarse el valor del mensaje del servidor a nuestra variable de mensaje de servidor, por otra parte, el método validador de la conexión, utiliza la variable isValidConnection (mIsValidConnection en VB) para no intentar nuevamente la conexión si esta es válida.  La cadena de conexión para la variable cnnHelper se toma del método GetConnectionString() de la variable sqlSettings (mSqlSettings en VB) que se encarga de generar la cadena de conexión en base a los parámetros establecidos en las variables de conexión.


Hasta aquí, tenemos ya la primera parte del DataHelper, y los instrumentos que se utilizarán a través de los métodos subsecuentes del helper. La funcionalidad básica será adicionada a esta clase método por método según las necesidades de funcionalidad para con la base de datos.


Antes de continuar, terminemos el complemento de las variables declaradas a nivel de clase con las propiedades correspondientes, mismas que serán de utilidad para exponer lo que sucede dentro del helper hacia el exterior, para informes o toma de decisiones. Debemos tener en cuenta que como los valores de las variables se asignan dentro del helper las propiedades tendrán que ser de solo lectura a modo de propiedades informativas. Así pues, agreguemos las siguientes propiedades:


VB


Public ReadOnly Property SqlSettings() As IDbSettings


 


    Get


        Return mSqlSettings


    End Get


 


End Property


 


Public ReadOnly Property ErrorNumber() As Integer


 


    Get


        Return mErrorNumber


    End Get


 


End Property


 


Public ReadOnly Property MessageHelper() As String


 


    Get


        Return mMessageHelper


    End Get


 


End Property


 


Public ReadOnly Property MessageServer() As String


 


    Get


        Return mMessageServer


    End Get


 


End Property


C#


public IDbSettings SqlSettings


{


    get


    {


        return sqlSettings;


    }


}


public int ErrorNumber


{


    get


    {


        return errorNumber;


    }


}


public string MessageHelper


{


    get


    {


        return messageHelper;


    }


}


public string MessageServer


{


    get


    {


        return messageServer;


    }


}


Por el momento será todo para la primera parte, en la segunda parte terminaremos con la definición del data helper, pero aún faltará subir un peldaño con la definición del Data Access Component, así que tendremos que ir un poco más rápido con los temas para no perder la continuidad.


Pues bien, nos estaremos viendo en el siguiente post.


La liga para descarga de los archivos relacionados con este artículo:
http://code.msdn.microsoft.com/datahelper


Continuar con la siguiente parte:
http://msmvps.com/blogs/otelis/archive/2009/03/15/arquitectura-definici-243-n-de-un-datahelper-parte-2.aspx


Saludos…


Octavio Telis

One thought on “Arquitectura – Definición de un DataHelper, Parte 1”

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>