Direto ao ponto: Efeitos colaterais de um ORM no seu domínio

Post on 13-Apr-2017

41 views 0 download

Transcript of Direto ao ponto: Efeitos colaterais de um ORM no seu domínio

Direto ao ponto

Software em contexto

Os efeitos colaterais de um ORM no seu domínio

Entity Framework vs NHibernate

Agenda• Modelo de domínio e Persistence Ignorance• ORM, o que é?• Modelando um agregado

• Entidades• Objetos de valor

• Alterando uma entidade de um agregado• Considerações finais

Quem somos?Robson Castilho@nosborcastilho

Gustavo Fontes@GusFFontes

André Baltieri@andrebaltieri

José Roberto Araújo@jrobertofaraujo

Yan Justino@YanJustino

Modelo de domínio e Persistence Ignorance

• Uma abstração do problema de domínio• Contém a logica para resolver problemas do negocio• Não possui influencia de agentes externos

ORM – Object Ralational Mapping

• O que é?

Modelo de agragadoProgramação

IEnumerable<Sessao>SessoesPeriodoDeExibicao Exibicao

Sessao

Guid FilmeIdGuid SalaId

DateTime Databool EstaDisponivel

1..N

PeriodoDeExibicao

DateTime InicioDateTime Fim

Persistindo um agragado: Puro public sealed class Programacao : RaizDeAgregado {

public PeriodoDeExibicao Exibicao { get; private set; }

public IEnumerable<Sessao> Sessoes { get;}

public Programacao(PeriodoDeExibicao exibicao,List<Sessao> sessoes) { _sessoes = new List<Sessao>(); Exibicao = exibicao; sessoes.ForEach(s => AdicionarSessao(s)); } }

Persistindo um agragado: NHibernate public class Programacao : RaizDeAgregado { public virtual EF.PeriodoDeExibicao Exibicao { get; protected set;}

public virtual IList<Sessao> Sessoes { get ;}

protected Programacao() { }

public Programacao(EF.PeriodoDeExibicao exibicao,List<Sessao> sessoes) { essoes = new List<Sessao>(); Exibicao = exibicao; sessoes.ForEach(s => AdicionarSessao(s)); }

Persistindo um agragado: NHibernate public class Sessao : Entidade { public virtual Guid FilmeId { get; } public virtual Guid SalaId { get; }

public virtual DateTime Data { get; }

public virtual int IngressosVendidos { get; protected set; } public virtual bool Disponivel { get; protected set; }

protected Sessao() {

}

Mapeamento de entidade: NHibernate public class ProgramacaoMap : ClassMap<Programacao> { public ProgramacaoMap() { Id(p => p.Id);

Component(p => p.Exibicao, e => { e.Map(pe => pe.Inicio); e.Map(pe => pe.Fim);

});

HasMany(p => p.Sessoes) .KeyColumns .Add("ProgramacaoId")

.Cascade.AllDeleteOrphan() .Cascade.SaveUpdate();

Table("Programacao"); } }

Objeto de valor

Relacionamento com Entidade

Persistindo um agragado: Entity Framework public class Programacao : RaizDeAgregado {

public virtual ICollection<Sessao> Sessoes { get; private set; }

public PeriodoDeExibicao Exibicao { get; private set; }

private Programacao() { }

public Programacao(PeriodoDeExibicao exibicao,List<Sessao> sessoes) { Id = Guid.NewGuid(); Exibicao = exibicao; sessoes.ForEach(s => AdicionarSessao(s)); } }

Persistindo um agragado: Entity Framework public sealed class Sessao : Entidade { public Guid FilmeId { get; private set; } public Guid SalaId { get; private set; }

public Guid ProgramacaoId { get; private set; }

public DateTime Data { get; private set; } public int IngressosVendidos { get; private set; } public bool Disponivel { get; private set; }

private Sessao() {

}

Mapeamento de entidade: Entity Framework

public class ProgramacaoMap:EntityTypeConfiguration<Programacao> { public ProgramacaoMap() { HasKey(p => p.Id);

HasMany(p => p.Sessoes) .WithRequired() .HasForeignKey(_ => _.ProgramacaoId) .WillCascadeOnDelete(); ToTable(@"Programacao"); } }

public class PeriodoDeExibicaoMap:ComplexTypeConfiguration<PeriodoDeExibicao> { public PeriodoDeExibicaoMap() { Property(e => e.Inicio) .HasColumnName("Inicio") .HasColumnType("datetime");

Property(e => e.Fim) .HasColumnName("Fim") .HasColumnType("datetime"); } }

Alterando Agregado: Adicionando uma nova sessão com NH

public void Editar(Programacao programacao) { using (var tran = _session.BeginTransaction()) { _session.Update(programacao); tran.Commit(); }

}

public virtual void AdicionarSessao(Sessao sessao) { if (Exibicao.Disponivel()) _sessoes.Add(sessao); else throw new InvalidOperationException("Essa programação não está disponivel"); }

Alterando Agregado: Adicionando uma nova sessão com EF

public void AdicionarSessao(Sessao sessao) { if (Exibicao.Disponivel()) _Sessoes.Add(sessao); else throw new InvalidOperationException("Essa programação não está disponivel"); }

public void Editar(Programacao programacao) { _conexao.Entry<Programacao>(programacao).State = System.Data.Entity.EntityState.Modified; _conexao.SaveChanges(); }

Alterando Agregado: Removendo uma sessão com NH

public void Editar(Programacao programacao) { using (var tran = _session.BeginTransaction()) { _session.Update(programacao); tran.Commit(); }

}

public virtual void SessaoIndisponivel(Sessao sessao) { _sessoes.Remove(sessao); }

Alterando Agregado: Removendo uma sessão com EF

public void Editar(Programacao programacao) { _conexao.Entry<Programacao>(programacao).State = System.Data.Entity.EntityState.Modified; _conexao.SaveChanges(); }

public class SessaoMap:EntityTypeConfiguration<Sessao> { public SessaoMap() { HasKey(s => new { s.Id, s.ProgramacaoId }); } }

public void SessaoIndisponivel(Sessao sessao) { _Sessoes.Remove(sessao); }

Agregado: Trabalhando com listas somente leitura

public sealed class Programacao : RaizDeAgregado { private IList<Sessao> _sessoes;

public PeriodoDeExibicao Exibicao { get;}

public IEnumerable<Sessao> Sessoes { get { return _sessoes; } }

public Programacao(PeriodoDeExibicao exibicao,List<Sessao> sessoes) { _sessoes = new List<Sessao>(); Exibicao = exibicao; sessoes.ForEach(s => AdicionarSessao(s)); } }

Agregado: Trabalhando com listas somente leitura com NH

HasMany<Sessao>(Reveal.Member<Programacao>("Sessoes")) .KeyColumns .Add("ProgramacaoId") .Access.CamelCaseField(Prefix.Underscore) .Cascade.AllDeleteOrphan() .Cascade.SaveUpdate();

public class Programacao : RaizDeAgregado { private IList<Sessao> _sessoes;

public virtual EF.PeriodoDeExibicao Exibicao { get; }

public virtual IEnumerable<Sessao> Sessoes { get { return _sessoes; } }

Agregado: Trabalhando com listas somente leitura com EF public class Programacao : RaizDeAgregado { public static Expression<Func<Programacao, ICollection<Sessao>>> SessaoExpresson = f => f._Sessoes;

protected virtual ICollection<Sessao> _Sessoes { get; set; }

public IEnumerable<Sessao> Sessoes { get { return _Sessoes.ToList(); } }

}

HasMany(Programacao.SessaoExpresson) .WithRequired() .HasForeignKey(_ => _.ProgramacaoId) .WillCascadeOnDelete();

/SoftwareEmContexto

/softwareemcontexto

/softwareemcontexto

Nossos links

Referências• https://goo.gl/KUAttn• https://goo.gl/yB827x