Project Standard

12

I use the following project pattern:

WheretheInterfacewillonlycommunicatewiththeapplicationanditwillcommunicatewiththeRepository.Sotheinterfacewillhavenorestrictionsandnoknowledgeofhowcommunicationwiththedatabaseoccurs.InmycaseIusetheEntityFramework,butinthisschemeIcaneasilybeusingothermethodsofcommunication.

TheApplicationhastwoclassesforeachDomainclass:

publicclassCartasAplicacao{privatereadonlyIRepositorio<Cartas>repositorio;publicCartasAplicacao(IRepositorio<Cartas>repo){repositorio=repo;}publicvoidSalvar(Cartascarta){repositorio.Salvar(carta);}publicvoidExcluir(Cartascarta){repositorio.Excluir(carta);}publicIEnumerable<Cartas>ListarTodos(){returnrepositorio.ListarTodos();}publicCartasListarPorId(stringid){returnrepositorio.ListarPorId(id);}}

E:

publicclassCartasAplicacaoConstrutor{publicstaticCartasAplicacaoCartasAplicacaoEF(){returnnewCartasAplicacao(newCartasRepositorioEF());}}

IntheRepositoryEFIdothefollowing:

publicDbSet<SBE_ST_BannerRotativo>BannerRotativo{get;set;}publicDbSet<Cartas>Cartas{get;set;}publicContexto():base("BancoDados")
        {
            Database.SetInitializer<Contexto>(null);
        }

E:

 public class CartasRepositorioEF: IRepositorio<Cartas>
    {
        private readonly Contexto contexto;

        public CorpoDocenteRepositorioEF()
        {
            contexto = new Contexto();
        }
        public void Salvar(Cartas entidade)
        {
            if (entidade.Id > 0)
            {
                var cartaAlterar = contexto.Cartas.First(x => x.Id == entidade.Id);
                cartaAlterar.Descricao = entidade.Descricao;
                cartaAlterar.Imagem = entidade.Imagem;
                cartaAlterar.Nome = entidade.Nome;
            }
            else
            {
                contexto.CorpoDocente.Add(entidade);
            }
            contexto.SaveChanges();
        }

        public void Excluir(Cartas entidade)
        {
            var cartaAlterar = contexto.Cartas.First(x => x.Id == entidade.Id);
            contexto.Set<Cartas>().Remove(cartaAlterar );
            contexto.SaveChanges();
        }

        public IQueryable<Cartas> ListarTodos()
        {
            return contexto.Cartas;
        }

        public Cartas ListarPorId(int id)
        {
            return contexto.Cartas.FirstOrDefault(x => x.Id == id);
        }
    }

Then to use the Interface:

var bdcarta = CartasAplicacaoConstrutor.CartasAplicacaoEF();
bdcarta.Salvar(carta);

My doubts are about what the pros and cons are about this project template. If there are other patterns that are "better" than this one.

    
asked by anonymous 25.08.2014 / 14:10

1 answer

8

I find the separation unnecessary for your case at some points.

Separation into DLLs between Domain, Repository and Application is unnecessary because you yourself said that the Interface will communicate with the application, and the application will communicate with the Repository. As it is done, virtually all classes of all DLLs used to communicate between layers need to be public, which only leaves the project more complex and unnecessarily exposed (high coupling, low cohesion).

In this case, the three layers may perfectly be in the same DLL, separated only by namespace :

  • Application.Core
    • Application
    • Domain
    • EF Repository

This ensures that only Dominio and Aplicacao will be exposed to your interfaces, ensuring low coupling and high cohesion, as recommended in Software Engineering.

The existence of a repository ensures that the application is properly isolated from the database, enabling you to even remove the Entity Framework and use other database access and persistence technology. Better yet, each repository implements the IRepositorio interface, guaranteeing orthogonality in implementations. It would still be interesting to use a generic repository pattern, avoiding having to deploy repository to repository (which is not necessary and goes against Do not Repeat Yourself good practice). Here are some good examples of how to do this .

EDIT

To requests per comment, I am putting the implementation of a generic repository:

public class AplicacaoGenerica<T>
    where T: class
{
    private readonly IRepositorio<T> repositorio;

    public AplicacaoGenerica(IRepositorio<T> repo)
    {
        repositorio = repo;
    }

    public void Salvar(T entidade)
    {
        repositorio.Salvar(T);
    }

    public void Excluir(T entidade)
    {
        repositorio.Excluir(T);
    }

    public IEnumerable<T> ListarTodos()
    {
        return repositorio.ListarTodos();
    }

    public T ListarPorId(string id)
    {
        return repositorio.ListarPorId(id);
    }
}

public class RepositorioGenericoEF<T>: IRepositorio<T>
    where TEntity: class
{
    private readonly Contexto contexto;

    public RepositorioGenericoEF()
    {
        contexto = new Contexto();
    }
    public void Salvar(T entidade)
    {
        if (entidade.Id > 0)
        {
            contexto.Entry(entidade).State = EntityState.Modified;
        }
        else
        {
            contexto.Set<T>.Add(entidade);
        }

        contexto.SaveChanges();
    }

    public void Excluir(T entidade)
    {
        contexto.Set<T>().Remove(entidade);
        contexto.SaveChanges();
    }

    public IEnumerable<T> ListarTodos()
    {
        return contexto.Set<T>.ToList();
    }

    public T ListarPorId(int id)
    {
        return contexto.Set<T>.FirstOrDefault(x => x.Id == id);
    }
}

Therefore:

public class CartasAplicacao: AplicacaoGenerica<Cartas>
{

}

public class CartasRepositorioEF: RepositorioGenericoEF<Cartas>
{

}

I took this example as an inspiration: link

    
25.08.2014 / 14:50