Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

O TNF abre uma conexão com o banco de dados e inicia uma transação ao entrar em um método que utiliza o padrão. Assim, você pode usar a conexão com segurança neste método. No  No final do método, a transação é confirmada e a conexão é descartada. Se o método lançar qualquer exceção, a transação é revertida e a conexão é descartada. Desta forma, uma unidade de trabalho é tida como atômica. o TNF faz tudo isso automaticamente. todo UoW é tido como atômico.

Se uma um método que utiliza o UoW chama chamar outro método que também a o utiliza, ambos usam a mesma conexão e transação. Neste cenário o primeiro método fará o gerenciamento da conexão e da transação.

Uso Convencional

 

Alguns métodos utilizam UoW por default: 

  • ASP NET Core Controller Actions.
  • Serviços de Aplicação.
  • Todos os Métodos de Repositórios.

...

Vamos utilizar como exemplo o serviço de aplicação abaixo: 

Bloco de código
languagec#
firstline1
titlePersonAppService.cs
linenumberstrue
public class PersonAppService : IPersonAppService
{
    private readonly IPersonRepository _personRepository;
    private readonly IStatisticsRepository _statisticsRepository;

    public PersonAppService(IPersonRepository personRepository, IStatisticsRepository statisticsRepository)
    {
        _personRepository = personRepository;
        _statisticsRepository = statisticsRepository;
    }

    public void CreatePerson(CreatePersonInput input)
    {
        var person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
        _personRepository.Insert(person);
        _statisticsRepository.IncrementPeopleCount();
    }
}

No método CreatePerson, estamos inserindo uma pessoa usando o repositório de pessoas IPersonRepository e incrementando a contagem total de pessoas usando o repositório de estatísticas IStatisticsRepository. Ambos os repositórios compartilham mesma conexão e transação neste exemplo, já que o método de serviço de aplicação é a unidade de trabalho um UoW por padrão. O TNF abre uma conexão de banco de dados e inicia uma transação ao inserir o método CreatePerson e confirmar a transação no final do método deste se nenhuma exceção for lançada. Dessa forma, todas as operações de banco de dados no método CreatePerson se tornam atômicas.

...

Existem cenários onde você precisa ter o controle do UoW de forma explicita. 

UnitOfWork Attribute

Bloco de código
languagec#
firstline1
titleCreatePerson Method
linenumberstrue
[UnitOfWork]
public void CreatePerson(CreatePersonInput input)
{
    var person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
    _personRepository.Insert(person);
    _statisticsRepository.IncrementPeopleCount();
}

...

Uma segunda abordagem é a utilização da interface IUnitOfWorkManager , injetando ela em seu serviço:

...

Bloco de código
languagec#
firstline1
titleRemoveFriendship Method
linenumberstrue
[UnitOfWork(IsDisabled = true)]
public virtual void RemoveFriendship(RemoveFriendshipInput input)
{
    _friendshipRepository.Delete(input.Id);
}

Em algumas situações você pode precisar desabilita-lo: utilizando com um escopo limitado (UnitOfWorkScope). Observe que se um método com UoW chamar RemoveFriendship, a ação de desativar o UoW será ignorado se ele usar o mesmo UoW.

Trabalhando com UoW Não Transacional

Um UoW é transacional como por padrão. Em alguns casos especiais, a transação pode causar problemas, uma vez que pode bloquear algumas linhas ou tabelas no banco de dados (LOCK). Nestas situações, podemos desabilitar a transação através do atributo UnitOfWork:

Bloco de código
languagec#
firstline1
titleGetTasksOutput Method
linenumberstrue
[UnitOfWork(isTransactional: false)]
public GetTasksOutput GetTasks(GetTasksInput input)
{
    var tasks = _taskRepository.GetAllWithPeople(input.AssignedPersonId, input.State);
    return new GetTasksOutput
	{
    	Tasks = Mapper.Map<List<TaskDto>>(tasks)
	};
}

...

Se o seu método apenas lê dados ele pode ser seguramente não-transacional.

Se um método que utiliza UoW chama outro método que utiliza UoW, eles compartilham a mesma conexão e transação. O primeiro método gera a conexão e os outros a utilizam.

...

 Podemos alterar os valores padrão de todos os UoW na configuração de inicialização em nosso modulomódulo. Isso geralmente é feito no método PreInitialize:

...

Por exemplo, você pode querer executar algum código quando um UoW é concluído com êxito. Exemplo: 

Bloco de código
languagec#
firstline1
titleCreate Task Method Example
linenumberstrue
public void CreateTask(CreateTaskInput input)
{
    var task = new Task { Description = input.Description };

    if (input.AssignedPersonId.HasValue)
    {
        task.AssignedPersonId = input.AssignedPersonId.Value;
        _unitOfWorkManager.Current.Completed += (sender, args) => { /* TODO: Send email to assigned person */ };
    }

    _taskRepository.Insert(task);
}

 

 

 

...