Trilhas
/
C#
C#
/
Exercícios
/
ORM de uma vez só
ORM de uma vez só

ORM de uma vez só

Exercício de aprendizagem

Introdução

Ciclo de vida de recursos

resource-cleanup usa a interface IDispose para sinalizar que o recurso de algum objeto, ou outro estado do programa, precisava ser liberado ou redefinido quando o objeto não era mais necessário (e que depender do coletor de lixo não alcançaria isso nem ofereceria o nível de controle necessário) e que o método IDisposable.Dispose() era o lugar natural para essas operações de limpeza.

Existe outra construção, o bloco using, que permite, do ponto de vista de quem chama, reunir todo o gerenciamento do ciclo de vida dos recursos em uma única instrução.

using (var file = new File("my_secrets"))
{
    file.WriteSecret("xxxxxxx");
}

No exemplo acima, os recursos do sistema de arquivos associados a file serão liberados de volta para o sistema operacional quando o bloco using for encerrado.

Para que o padrão funcione, a variável na instrução using precisa ser um tipo de referência que implemente a interface IDisposable e precisa liberar recursos/redefinir o estado do programa em seu método Dispose().

O C# 8 introduz um refinamento desse padrão. Uma instrução using pode ser colocada no início de um bloco.

using var drawingResource = some_provided_or_new_object;
try
{
    drawingResource.DrawSomething();
}
catch (Exception)
{
    throw;
}

Quem programa em Java pode reconhecer isso como um análogo do mecanismo de gerenciamento automático de recursos introduzido no Java 7.

Instruções

Você está de volta ao trabalho no sistema ORM (Object Relationship Mapping) apresentado em object-relational-mapping.

Nossa análise de uso do ORM mostra que 95% das transações são executadas dentro de um único método que as chama, e foi decidido que seria mais adequado ter um único método do ORM que abrisse, gravasse e confirmasse uma transação.

O banco de dados tem os seguintes métodos de instância:

  • Database.BeginTransaction() inicia uma transação no banco de dados.
  • Database.Write(string data) grava dados no banco de dados dentro da transação. Se receber dados inválidos, uma exceção será lançada. Uma tentativa de chamar esse método sem que BeginTransaction() tenha sido chamado fará com que uma exceção seja lançada. Se for bem-sucedido, o estado interno do banco de dados mudará para DataWritten.
  • Database.EndTransaction() confirma a transação no banco de dados. Pode lançar uma exceção se não conseguir fechar a transação ou se Database.BeginTransaction() não tiver sido chamado.
  • Uma chamada a Database.Dispose() limpará o banco de dados se uma exceção for lançada durante uma transação. Isso mudará o estado do banco de dados para Closed.

1. Grave no banco de dados

Implemente o método Orm.Write() para iniciar uma transação no banco de dados, gravar os dados recebidos e confirmar a transação. Todas as exceções, incluindo InvalidOperationException, devem poder chegar até quem chamou, sem registro em log nem qualquer outra intervenção.

Database db = new Database();
Orm orm = new Orm(db);
orm.Write("good write");
// => database has an internal state of State.Closed
orm.Write("bad write");
// => an exception is thrown but database is left with an internal state of State.Closed
orm.Write("bad commit");
// => an exception is thrown but database is left with an internal state of State.Closed

2. Grave no banco de dados e retorne a quem chamou uma indicação de sucesso da gravação

Já se passaram alguns meses desde que Orm.Write() foi introduzido e há divisão na equipe. Muitos desenvolvedores gostariam que a ORM tratasse os erros quando exceções são lançadas e simplesmente retornasse uma indicação de sucesso para quem chamou.

Implemente o método Orm.WriteSafely() para iniciar uma transação no banco de dados, gravar os dados recebidos e confirmar a transação (como acima). Ele deve retornar true se a gravação foi bem-sucedida e false caso contrário. Não tente registrar a exceção em log.

Database db = new Database();
Orm orm = new Orm(db);
orm.WriteSafely("good write");
// => true
orm.WriteSafely("bad write");
// => false
orm.WriteSafely("bad commit");
// => false
Editar via GitHub O link abre em uma nova janela ou aba
C# Exercism

Tudo pronto para começar ORM de uma vez só?

Crie sua conta no Exercism para aprender e dominar C# com 62 conceitos178 exercícios e mentoria humana de verdade, tudo de graça.