Se uma classe implementa a interface IDisposable, o método Dispose() dela precisa ser chamado sempre que uma instância não for mais necessária. Isso normalmente é feito a partir de uma cláusula catch ou finally, ou da rotina Dispose() de quem a chamou. O Dispose() oferece a oportunidade de liberar recursos não gerenciados, como objetos do sistema operacional (que não são gerenciados pelo runtime do .NET), e de redefinir o estado interno dos recursos gerenciados.
Você está implementando um sistema de ORM (mapeamento objeto-relacional) sobre um banco de dados que foi fornecido por outra equipe.
O banco de dados é capaz de lidar com uma única transação por vez.
Não é preciso fazer registro em log nem nenhum outro tipo de tratamento de erros nesta etapa.
Repare que, internamente, o banco de dados passa por uma série de estados: Closed, TransactionStarted, DataWritten, Invalid, Closed. Você pode contar com o fato de que o banco de dados está no estado Closed no início de cada exercício.
O banco de dados tem os seguintes métodos de instância:
Database.BeginTransaction() inicia uma transação no banco de dados. Se for chamado quando o banco de dados não está no estado Closed, uma exceção é lançada. Se der certo, o estado interno do banco de dados muda para TransactionStarted.Database.Write(string data) grava dados no banco de dados dentro da transação. Se receber dados inválidos, uma exceção é lançada. Tentar chamar esse método sem que BeginTransaction() tenha sido chamado também lança uma exceção. Se der certo, o estado interno do banco de dados muda para DataWritten.Database.EndTransaction() confirma a transação no banco de dados. Ele pode lançar uma exceção se não conseguir fechar a transação ou se Database.BeginTransaction() não tiver sido chamado.Database.Dispose() limpa o banco de dados se uma exceção for lançada durante uma transação. Isso muda o estado do banco de dados para Closed.O estado do banco de dados pode ser acessado com database.DbState.
O estado do banco de dados pode ser definido como um dos seguintes:
Implemente Orm.Begin() para iniciar uma transação no banco de dados. Se o banco de dados não começar com um estado interno State.Closed, ele lança uma InvalidOperationException.
var orm = new Orm(new Database());
orm.Begin();
// => database has an internal state of State.TransactionStarted
Implemente Orm.Write() para gravar alguns dados no banco de dados. Se o banco de dados não começar com um estado interno State.TransactionStarted ou se dados inválidos forem gravados, uma InvalidOperationException é lançada. Se a gravação falhar, o Orm deve limpar o banco de dados.
var orm = new Orm(new Database());
orm.Begin();
orm.Write("some data");
// => database has an internal state of State.DataWritten
orm.Write("bad write");
// => database has an internal state of State.Closed
Implemente Orm.Commit() para confirmar os dados. Se a confirmação falhar, limpe o banco de dados. Se o banco de dados não começar com um estado interno State.DataWritten, uma InvalidOperationException é lançada.
var orm = new Orm(new Database());
orm.Begin();
orm.Write("some data");
orm.Commit();
// => database has an internal state of State.Closed
orm.Begin();
orm.Write("bad commit");
orm.Commit();
// => database has an internal state of State.Closed
Implemente a interface IDisposable na classe Orm. É garantido que a chamada terá sucesso.
var db = new Database();
var orm = new Orm(db);
orm.Begin();
orm.Write("some data");
orm.Dispose();
// => database has an internal state of State.Closed
Crie sua conta no Exercism para aprender e dominar C# com 62 conceitos178 exercícios e mentoria humana de verdade, tudo de graça.