Implementación de Patron Repository con IoC y DI en Web API

Dependencias:

Instalar el siguiente paquete utilizando la consola de Paquetes Nuget

Install-Package Unity -Version 4.0.1

PerRequestLifetimeManager.cs

namespace WebApiClient.App_Start
{    
    using Microsoft.Practices.Unity;
    using System;
    using System.Web; 

    /// <summary>
    /// Clase que encapsula la gestión del ciclo de vida de los objetos que son generados
    /// por el patron de Inyección de Dependencias.
    /// </summary>
    public class PerRequestLifetimeManager: LifetimeManager, IDisposable
    {        
        // Clave del storage.
        private readonly Guid Key = Guid.NewGuid();     
        
        /// <summary>
        /// Método que obtiene el objeto que se encuentra activo en el storage.
        /// </summary>
        /// <returns>Objeto.</returns>
        public override object GetValue()
        {
            if (HttpContext.Current != null && HttpContext.Current.Items.Contains(Key))            
                return HttpContext.Current.Items[Key];            
            else            
                return null;            
        }

        /// <summary>
        /// Método para quitar el objeto del storage.
        /// </summary>
        public override void RemoveValue()
        {
            if (HttpContext.Current != null)            
                HttpContext.Current.Items.Remove(Key);            
        }

        /// <summary>
        /// Método para almacenar un objeto en el storage.
        /// </summary>
        /// <param name="newValue">Objeto.</param>
        public override void SetValue(object newValue)
        {
            if (HttpContext.Current != null)            
                HttpContext.Current.Items[Key] = newValue;            
        }

        /// <summary>
        /// Método para liberar los recursos de memoria.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Método para liberar los recursos cuando sea requerido.
        /// </summary>
        /// <param name="disposing">Valor que indica si se desea liberar los recursos.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)            
                RemoveValue();            
        }
    }
}

IoCFactory.cs

namespace WebApiClient.App_Start
{    
    using Domain.Contracts;
    using Infrastructure.Implementation;
    using Infrastructure.Persistence;
    using Microsoft.Practices.Unity;
    using System.Data.Entity;    

    /// <summary>
    /// Clase que encapsula la implementación del patrón de
    /// inyección de dependencias e inversión de control para
    /// el repositorio genérico y unidad de trabajo.
    /// </summary>
    public class IoCFactory
    {        
		// Propiedad que encapsula el contenedor.		
        private static readonly IUnityContainer UnityContainer = new UnityContainer();
				
		// Propiedad que expone el contenedor.		
        public static IUnityContainer Container { get { return UnityContainer; } }
        
        /// <summary>
        /// Método encargado de llevar acabo los patrones de IoC y DI para el repositorio genérico
        /// y unidad de trabajo.
        /// </summary>
        public static void RegisterTypes()
        {
            UnityContainer.RegisterType(typeof(IRepository<>), typeof(Repository<>));
            UnityContainer.RegisterType(typeof(IUnitOfWork), typeof(UnitOfWork));
            UnityContainer.RegisterType(typeof(DbContext), typeof(Context));
            UnityContainer.RegisterInstance(new DbContextAdapter(UnityContainer.Resolve<DbContext>()), new PerRequestLifetimeManager());            
            UnityContainer.RegisterType<IObjectSetFactory>(new InjectionFactory(x => x.Resolve<DbContextAdapter>()));
            UnityContainer.RegisterType<IObjectContext>(new InjectionFactory(x => x.Resolve<DbContextAdapter>()));
        }        
    }
}

 FabricaCategoria.cs 

namespace WebApiClient.App_Code.Fabricas
{    
    using Infrastructure.Contracts;
    using Domain.Entities;    

    /// <summary>
    /// Fabrica para controlador de categoría.
    /// </summary>
    public class FabricaCategoria
    {        
        // Repositorio que encapsula la gestión de categorias.        
        private IRepository<Categoria> repositorioCategoria;

        // Unidad de trabajo.        
        private IUnitOfWork unidadTrabajo;
 
        // Propiedad publica para recuperar el repositorio de categoría.        
        public IRepository<Categoria> RepositorioCategoria { get { return repositorioCategoria; }}

        // Propiedad publica para recuperar la unidad de trabajo.        
        public IUnitOfWork UnidadTrabajo { get { return unidadTrabajo; }}        
        
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="repositorioCategoria">Repositorio Categoria.</param>
        /// <param name="unidadTrabajo">Unidad de Trabajo.</param>
        public FabricaCategoria(IRepository<Categoria> repositorioCategoria, IUnitOfWork unidadTrabajo)
        {
            this.repositorioCategoria = repositorioCategoria;
            this.unidadTrabajo = unidadTrabajo;
        }        
    }
}

CategoriaController.cs

namespace WebApiClient.Controllers
{    
    using Microsoft.Practices.Unity;
    using Resources;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http;
    using System.Web.Http.Cors;
    using App_Code;
    using App_Code.Fabricas;
    using App_Start;

    /// <summary>
    /// Controlador que contiene WebMethods para gestionar la información de las categorías.
    /// </summary>
    [EnableCors("*", "*", "*")]
    public class CategoriaController : BaseController
    {        
        // Variable que encapsula la fabrica para la gestión de categorias.        
        private FabricaCategoria fabricaCategoria;        
        
        /// <summary>
        /// Constructor.
        /// </summary>
        public CategoriaController()
        {
            fabricaCategoria = IoCFactory.Container.Resolve<FabricaCategoria>();
        }

        /// <summary>
        /// Método para obtener todas las categorías de un tipo.
        /// </summary>
        /// <param name="tipoCategoriaId">Identificador del tipo de categoría.</param>
        /// <returns>HttpResponseMessage que contiene el resultado de la ejecución del método.</returns>
        [HttpGet]
        public HttpResponseMessage ObtenCategorias(int tipoCategoriaId)
        {            
            try
            {
				return Request.CreateResponse(HttpStatusCode.OK, fabricaCategoria.RepositorioCategoria.Find(x => x.TipoCategoriaId == tipoCategoriaId && x.Activo).OrderBy(x => x.Nombre).ToList());                
            }
            catch (Exception ex)
            {
				return Request.CreateResponse(HttpStatusCode.InternalServerError, "No fue posible obtener la información de las categorias.");                
            }            
        }
    }
}

 

Patrón Repository en C#

IObjectContext.cs

namespace Infrastructure.Contracts
{
    using System;

    /// <summary>
    /// Interfaz que encapsula firmas de métodos del contexto.
    /// </summary>
    public interface IObjectContext:IDisposable
    {
        /// <summary>
        /// Método para guardar cambios en el contexto.
        /// </summary>
        void SaveChanges();

        /// <summary>
        /// Método para revertir una transacción.
        /// </summary>
        void RollBack();
    }
}

 IObjectSetFactory.cs

namespace Infrastructure.Contracts
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Core.Objects; 

    /// <summary>
    /// Interfaz que encapsula las firmas de los métodos de la fabrica encargada de gestionar la instancia
    /// de las entidades y su estado.
    /// </summary>
    public interface IObjectSetFactory: IDisposable
    {
        /// <summary>
        /// Método para crear objetos del contexto.
        /// </summary>
        /// <typeparam name="T">Tipo de entidad.</typeparam>
        /// <returns>Fabrica.</returns>
        IObjectSet<T> CreateObjectSet<T>() where T : class;

        /// <summary>
        /// Método para cambiar el estado de una entidad.
        /// </summary>
        /// <param name="entity">Entidad.</param>
        /// <param name="state">Estado.</param>
        void ChangeObjectState(object entity, EntityState state);
    }
}

 IRepository.cs

namespace Infrastructure.Contracts
{    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;    

    /// <summary>
    /// Interfaz que encapsula las firmas de los métodos del repositorio genérico.
    /// </summary>
    /// <typeparam name="T">Tipo de clase de la que se desea crear el repositorio.</typeparam>
    public interface IRepository<T> where T : class
    {        
        /// <summary>
        /// Método para agregar una entidad al contexto.
        /// </summary>
        /// <param name="entity">Entidad.</param>
        void Insert(T entity);        
        
        /// <summary>
        /// Método para eliminar una entidad del contexto.
        /// </summary>
        /// <param name="entity">Entidad.</param>
        void Delete(T entity);
        
        /// <summary>
        /// Método para actualizar una entidad del contexto.
        /// </summary>
        /// <param name="entity">Entidad.</param>
        void Update(T entity);
        
        /// <summary>
        /// Método para obtener una entidad que satisfaga una expresión lambda.
        /// </summary>
        /// <param name="where">Expresión lambda.</param>
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en la entidad.</param>
        /// <returns>Entidad.</returns>
        T Single(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);
        
        /// <summary>
        /// Método para obtener la primera entidad que satisface una expresión lambda.
        /// </summary>
        /// <param name="where">Expresión lambda.</param>
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en la entidad.</param>
        /// <returns>Entidad.</returns>
        T First(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);
        
        /// <summary>
        /// Método para obtener todos los registros de una entidad.
        /// </summary>
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en cada una de las entidades.</param>
        /// <returns>Conjunto de entidades.</returns>
        IEnumerable<T> GetAll(params Expression<Func<T, object>>[] includeProperties);

        /// <summary>
        /// Método para obtener todos aquellos registros de una entidad que satisfacen una expresión lambda.
        /// </summary>
        /// <param name="where">Expresión lambda.</param>
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en cada una de las entidades.</param>
        /// <returns>Entidades</returns>
        IEnumerable<T> Find(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);

        /// <summary>
        /// Método para obtener todos los registros de una entidad de forma paginada.
        /// </summary>
        /// <param name="pageNumber">Número de página.</param>
        /// <param name="pageSize">Tamaño de página.</param>
        /// <param name="totalPages">Total de páginas.</param>
        /// <param name="totalElements">Total de elementos.</param>
        /// <param name="orderBy">Criterio de ordenamiento y propiedad por la que se va a ordenar.</param>        
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en cada una de las entidades.</param>
        /// <returns>Conjunto de entidades paginadas.</returns>
        IEnumerable<T> GetAllWithPagination(int pageNumber, int pageSize, out int totalPages, out int totalElements, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, params Expression<Func<T, object>>[] includeProperties);
        
        /// <summary>
        /// Método para obtener de forma paginada todos aquellos registros de una entidad que satisfacen una expresión lambda.
        /// </summary>
        /// <param name="pageNumber">Número de página.</param>
        /// <param name="pageSize">Tamaño de página.</param>
        /// <param name="totalPages">Total de páginas.</param>
        /// <param name="totalElements">Total de elementos.</param>
        /// <param name="where">Expresión lambda.</param>
        /// <param name="orderBy">Criterio de ordenamiento y propiedad por la que se va a ordenar.</param>        
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en cada una de las entidades.</param>
        /// <returns>Entidades.</returns>
        IEnumerable<T> FindWithPagination(int pageNumber, int pageSize, out int totalPages, out int totalElements, Expression<Func<T, bool>> where, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, params Expression<Func<T, object>>[] includeProperties);
    }
}

IUnitOfWork.cs

namespace Infrastructure.Contracts
{
    /// <summary>
    /// Interfaz que encapsula las firmas de los métodos de la unidad de trabajo.
    /// </summary>
    public interface IUnitOfWork
    {        
        /// <summary>
        /// Método para comprometer una transacción.
        /// </summary>
        void Commit();
        
        /// <summary>
        /// Método para revertir una transacción.
        /// </summary>
        void RollBack();        
    }
}

DbContextAdapter.cs

namespace Infrastructure.Implementation
{    
    using Infrastructure.Contracts;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Core.Objects;
    using System.Linq;    
    
    /// <summary>
    /// Clase que encapsula un adaptador para el contexto de base de datos.
    /// </summary>
    public class DbContextAdapter : IObjectSetFactory, IObjectContext
    {
        // Variable que encapsula la instancia del contexto.        
        private readonly ObjectContext Context;        
        
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="context">Contexto.</param>
        public DbContextAdapter(DbContext context)
        {
            Context = context.GetObjectContext();
        }

        /// <summary>
        /// Método para guardar cambios en el contexto.
        /// </summary>
        public void SaveChanges()
        {
            Context.SaveChanges();
        }
        
        /// <summary>
        /// Método para revertir una transacción.
        /// </summary>
        public void RollBack()
        {
            IEnumerable<object> _objects = from e in Context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Deleted)
                                             select e.Entity;

            Context.Refresh(RefreshMode.StoreWins, _objects);

            IEnumerable<object> AddedCollection = from e in Context.ObjectStateManager.GetObjectStateEntries(EntityState.Added)
                                                  select e.Entity;

            foreach (object addedEntity in AddedCollection)
                Context.Detach(addedEntity);
        }
        
        /// <summary>
        /// Método para crear objetos del contexto.
        /// </summary>
        /// <typeparam name="T">Tipo de entidad.</typeparam>
        /// <returns>Fabrica.</returns>
        public IObjectSet<T> CreateObjectSet<T>() where T : class
        {
            return Context.CreateObjectSet<T>();
        }        
        
        /// <summary>
        /// Método para cambiar el estado de una entidad.
        /// </summary>
        /// <param name="entity">Entidad.</param>
        /// <param name="state">Estado.</param>
        public void ChangeObjectState(object entity, EntityState state)
        {
            Context.ObjectStateManager.ChangeObjectState(entity, state);
        }
        
        /// <summary>
        /// Método para liberar el contexto.
        /// </summary>
        public void Dispose()
        {
            Context.Dispose();
        }                
    }
}

DbContextExtensions.cs

namespace Infrastructure.Implementation
{    
    using System.Data.Entity;
    using System.Data.Entity.Core.Objects;
    using System.Data.Entity.Infrastructure;    

    /// <summary>
    /// Clase que contiene métodos de extensión del contexto.
    /// </summary>
    public static class DbContextExtensions
    {        
        /// <summary>
        /// Método para obtener la instancia del contexto.
        /// </summary>
        /// <param name="dbContext">Contexto.</param>
        /// <returns>Instancia del contexto.</returns>
        public static ObjectContext GetObjectContext(this DbContext dbContext)
        {
            return ((IObjectContextAdapter)dbContext).ObjectContext;
        }     
    }
}

Repository.cs

namespace Infrastructure.Implementation
{    
    using Infrastructure.Contracts;    
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Core.Objects;
    using System.Linq;
    using System.Linq.Expressions; 

    /// <summary>
    /// Clase que encapsula la implementación de los métodos del repositorio genérico.
    /// </summary>
    public class Repository<T> : IRepository<T> where T : class
    {        
        // Interface IObjectSet.        
        private readonly IObjectSet<T> ObjectSet;
		
        // Interface IObjectSetFactory.        
        private readonly IObjectSetFactory ObjectSetFactory;        
        
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="objectSetFactory">Fabrica de entidades.</param>
        public Repository(IObjectSetFactory objectSetFactory)
        {
            ObjectSet = objectSetFactory.CreateObjectSet<T>();
            ObjectSetFactory = objectSetFactory;
        }
        
        /// <summary>
        /// Método que proporciona una instancia para evaluar consultas.
        /// </summary>
        /// <returns>Instancia con funcionalidad para evaluar consultas.</returns>
        public IQueryable<T> AsQueryable()
        {
            return ObjectSet;
        }        
        
        /// <summary>
        /// Método para agregar una entidad al contexto.
        /// </summary>
        /// <param name="entity">Entidad.</param>
        public void Insert(T entity)
        {
            ObjectSet.AddObject(entity);
        }        
        
        /// <summary>
        /// Método para eliminar una entidad del contexto.
        /// </summary>
        /// <param name="entity">Entidad.</param>
        public void Delete(T entity)
        {
            ObjectSet.DeleteObject(entity);
        }

        /// <summary>
        /// Método para actualizar una entidad del contexto.
        /// </summary>
        /// <param name="entity">Entidad.</param>
        public void Update(T entity)
        {
            ObjectSet.Attach(entity);
            ObjectSetFactory.ChangeObjectState(entity, EntityState.Modified);
        }

        /// <summary>
        /// Método para obtener una entidad que satisfaga una expresión lambda.
        /// </summary>
        /// <param name="where">Expresión lambda.</param>
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en la entidad.</param>
        /// <returns>Entidad.</returns>
        public T Single(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
        {
            IQueryable<T> _query = AsQueryable();
            _query = PerformInclusions(includeProperties, _query);
            return _query.Single(where);
        }

        /// <summary>
        /// Método para obtener la primera entidad que satisface una expresión lambda.
        /// </summary>
        /// <param name="where">Expresión lambda.</param>
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en la entidad.</param>
        /// <returns>Entidad.</returns>
        public T First(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
        {
            IQueryable<T> _query = AsQueryable();
            _query = PerformInclusions(includeProperties, _query);
            return _query.FirstOrDefault(where);
        }

        /// <summary>
        /// Método para obtener todos los registros de una entidad.
        /// </summary>
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en cada una de las entidades.</param>
        /// <returns>Conjunto de entidades.</returns>
        public IEnumerable<T> GetAll(params Expression<Func<T, object>>[] includeProperties)
        {
            IQueryable<T> _query = AsQueryable();
            return PerformInclusions(includeProperties, _query);
        }

        /// <summary>
        /// Método para obtener todos aquellos registros de una entidad que satisfacen una expresión lambda.
        /// </summary>
        /// <param name="where">Expresión lambda.</param>
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en cada una de las entidades.</param>
        /// <returns>Entidades.</returns>
        public IEnumerable<T> Find(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
        {
            IQueryable<T> _query = AsQueryable();
            _query = PerformInclusions(includeProperties, _query);
            return _query.Where(where);
        }

        /// <summary>
        /// Método para incluir en una consulta una o mas propiedades de navegación.
        /// </summary>
        /// <param name="includeProperties">Propiedades de navegación.</param>
        /// <param name="query">Consulta.</param>
        /// <returns>Consulta con las propiedades incluidas.</returns>
        private static IQueryable<T> PerformInclusions(IEnumerable<Expression<Func<T, object>>> includeProperties, IQueryable<T> query)
        {
            return includeProperties.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
        }

        /// <summary>
        /// Método para obtener todos los registros de una entidad de forma paginada.
        /// </summary>
        /// <param name="pageNumber">Número de página.</param>
        /// <param name="pageSize">Tamaño de página.</param>
        /// <param name="totalPages">Total de páginas.</param>
        /// <param name="totalElements">Total de elementos.</param>
        /// <param name="orderBy">Criterio de ordenamiento y propiedad por la que se va a ordenar.</param>        
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en cada una de las entidades.</param>
        /// <returns>Conjunto de entidades paginadas.</returns>
        public IEnumerable<T> GetAllWithPagination(int pageNumber, int pageSize, out int totalPages, out int totalElements, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, params Expression<Func<T, object>>[] includeProperties)
        {
            if (pageNumber < 1 || pageSize < 1)
            {
                totalElements = 0;
                totalPages = 0;
                throw new ArgumentOutOfRangeException(null, "Los valores para número y tamaño de página deben ser mayores a 0.");
            }
            else
            {
                IQueryable<T> _query = AsQueryable();
                _query = PerformInclusions(includeProperties, _query);

                if (orderBy != null)
                    _query = orderBy(_query);

                totalElements = _query.Count();
                totalPages = CalculateTotalPages(_query.Count(), pageSize);

                return _query.Skip(GetSkip(pageNumber, pageSize)).Take(pageSize);
            }
        }

        /// <summary>
        /// Método para obtener de forma paginada todos aquellos registros de una entidad que satisfacen una expresión lambda.
        /// </summary>
        /// <param name="pageNumber">Número de página.</param>
        /// <param name="pageSize">Tamaño de página.</param>
        /// <param name="totalPages">Total de páginas.</param>
        /// <param name="totalElements">Total de elementos.</param>
        /// <param name="where">Expresión lambda.</param>
        /// <param name="orderBy">Criterio de ordenamiento y propiedad por la que se va a ordenar.</param>        
        /// <param name="includeProperties">Propiedades de navegación que se desea incluir en cada una de las entidades.</param>
        /// <returns>Entidades.</returns>
        public IEnumerable<T> FindWithPagination(int pageNumber, int pageSize, out int totalPages, out int totalElements, Expression<Func<T, bool>> where, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, params Expression<Func<T, object>>[] includeProperties)
        {
            if (pageNumber < 1 || pageSize < 1)
            {
                totalPages = 0;
                totalElements = 0;
                throw new ArgumentOutOfRangeException(null, "Los valores para número y tamaño de página deben ser mayores a 0.");
            }
            else
            {
                IQueryable<T> _query = AsQueryable();
                _query = (PerformInclusions(includeProperties, _query)).Where(where);

                if (orderBy != null)
                    _query = orderBy(_query);

                totalElements = _query.Count();
                totalPages = CalculateTotalPages(_query.Count(), pageSize);

                return _query.Skip(GetSkip(pageNumber, pageSize)).Take(pageSize);
            }
        }

        /// <summary>
        /// Método para calcular el total de páginas.
        /// </summary>
        /// <param name="totalItems">Total de elementos.</param>
        /// <param name="pageSize">Tamaño de la página.</param>
        /// <returns>Total de páginas.</returns>
        private int CalculateTotalPages(int totalItems, int pageSize)
        {
            int _totalPages = -1;

            if (totalItems == 0)
                _totalPages = 0;
            else if ((totalItems % pageSize) == 0)
                _totalPages = totalItems / pageSize;
            else
                _totalPages = (totalItems / pageSize) + 1;

            return _totalPages;
        }

        /// <summary>
        /// Método para saber cuantos elementos se van a omitir.
        /// </summary>
        /// <param name="pageNumber">Número de página.</param>
        /// <param name="pageSize">Tamaño de la página.</param>
        /// <returns>Número de elementos que se deberan de omitir.</returns>
        private int GetSkip(int pageNumber, int pageSize)
        {
            return (pageSize * (pageNumber - 1));
        }
    }
}

UnitOfWork.cs

namespace Infrastructure.Implementation
{    
    using Infrastructure.Contracts;
    using System;    

    /// <summary>
    /// Clase que encapsula la implementación de los métodos de la unidad de trabajo.
    /// </summary>
    public class UnitOfWork : IUnitOfWork, IDisposable
    {        
        // Interface IObjectContext.        
        private readonly IObjectContext ObjectContext;        
        
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="objectContext">Instancia del contexto.</param>
        public UnitOfWork(IObjectContext objectContext)
        {
            ObjectContext = objectContext;
        }
        
        /// <summary>
        /// Método para comprometer una transacción.
        /// </summary>
        public void Commit()
        {
            ObjectContext.SaveChanges();
        }        
        
        /// <summary>
        /// Método para revertir una transacción.
        /// </summary>
        public void RollBack()
        {
            ObjectContext.RollBack();
        }		
        
        /// <summary>
        /// Método para liberar la instancia del contexto.
        /// </summary>
        public void Dispose()
        {
            if (ObjectContext != null)            
                ObjectContext.Dispose();            

            GC.SuppressFinalize(this);
        }        
    }
}

 

 

Validar correo electrónico en C#

        /// <summary>
        /// Método para validar una dirección de correo electrónico.
        /// </summary>
        /// <param name="email">Correo electrónico a validar.</param>
        /// <returns>Resultado de la validación.</returns>
        public bool ValidateEmail(string email)
        {
            return Regex.IsMatch(email, "^([\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([\\w-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
        }

 

Switch(Type) en C#

       private bool SwitchWithDataType(Type dataType, object value)
        {
            bool result = false;

            Dictionary<Type, Action> @switch = new Dictionary<Type, Action>
            {
                {
                    typeof(short), () => { result = TryParseToShort(value); }
                },
                {
                    typeof(int), () =>{ result= TryParseToInt(value); }
                },
                {
                    typeof(long), () =>{ result= TryParseToLong(value); }
                },
                {
                    typeof(string), ()=>{ result=  TryParseToString(value); }
                }
            };

            @switch[dataType]();

            return result;
        }