Как я могу сохранить свой .NET API сухоC#

Место общения программистов C#
Ответить
Гость
 Как я могу сохранить свой .NET API сухо

Сообщение Гость »

Я недавно пытался создать API .NET, который следует за шаблоном CQRS с Mediatr & Entity Framework. Я столкнулся с некоторыми проблемами с удержанием дубликата кода в моем проекте. Будьте достаточно просты, используя стандартную обработку медиатр: < /p>

Код: Выделить всё

public class CreateCustomerHandler(DbContext context): IRequestHandler
{
public async Task Handle(CreateCustomerCommand request, CancellationToken cancellationToken)
{
var c = new Customer()
{
Name = request.Name
};
await context.Customer.AddAsync(c, cancellationToken);
await context.SaveChangesAsync(cancellationToken);
return c;
}
}
Теперь скажем, что для клиента добавлено требование, которое должно быть создано с помощью объекта пользователя , с возможностью добавления дополнительных пользователей на более позднее срок. Обработчик теперь выглядит так: < /p>

Код: Выделить всё

public class CreateCustomerHandler(DbContext context): IRequestHandler
{
public async Task Handle(CreateCustomerCommand request, CancellationToken cancellationToken)
{
var c = new Customer()
{
Name = request.Name
};
await context.Customer.AddAsync(c, cancellationToken);

var u = new User()
{
CustomerId = c.Guid
};
await context.User.AddAsync(u, cancellationToken);

await context.SaveChangesAsync(cancellationToken);
return c;
}
}
И мне понадобится другой обработчик, чтобы добавить пользователя к существующему клиенту , который будет выглядеть как:

Код: Выделить всё

public class CreatUserHandler(DbContext context): IRequestHandler
{
public async Task Handle(CreateUserCommand request, CancellationToken cancellationToken)
{
var u = new User()
{
CustomerId = request.CustomerId
};
await context.User.AddAsync(u, cancellationToken);

await context.SaveChangesAsync(cancellationToken);
return u;
}
}
Теперь, учитывая два вышеупомянутые обработчики, скажем, как мы создаем пользователь , мне нужно было бы повторить изменения в оба < /strong> обработчики, которые не сухие. Я ценю, что в этом простом примере это не было бы большой проблемой, но, конечно, должен быть какой -то способ удаления этого дубликата кода, поэтому мне не нужно вносить изменения в несколько обработчиков. < /P>
что я пробовал:

1. Использование событий MediaT /> Я попытался решить эту проблему с помощью MediaTr События:

Код: Выделить всё

public class CreateCustomerHandler(DbContext context): IRequestHandler
{
public async Task Handle(CreateCustomerCommand request, CancellationToken cancellationToken)
{
var c = new Customer()
{
Name = request.Name
};
await context.Customer.AddAsync(c, cancellationToken);

await _mediator.Publish(
new CustomerCreatedNotification{
Customer = c
}
);

await context.SaveChangesAsync(cancellationToken);
return c;
}
}
, а затем обрабатывать создание пользователя в Customer -CreatedNotificationHandler . В идеале я хочу, чтобы создание клиента и пользователя было транзакционным, что не достигается этим методом.
2. выполнение icommands изнутри других обработчиков
, которые я реализовал следующим образом:

Код: Выделить всё

public class CreateCustomerHandler(DbContext context, IMediator mediator): IRequestHandler
{
public async Task Handle(CreateCustomerCommand request, CancellationToken cancellationToken)
{
var c = new Customer()
{
Name = request.Name
};

await context.Customer.AddAsync(c, cancellationToken);

var createUserCommand = new CreateUserCommand()
{
AccountId = c.Guid
};
await mediator.Send(createUserCommand, cancellationToken);

await context.SaveChangesAsync(cancellationToken);

return c;
}
}
Это кажется лучше с сухой перспективы, однако я прочитал многочисленные статьи, описывающие эту реализацию как код, так как Icommands не будет «самостоятельно».
3. [HttpPost]
public async Task CreateCustomer(CreateCustomerRequest request, CancellationToken cancellationToken)
{
var command = request.Adapt();

var customer = await mediator.Send(command, cancellationToken);

var createUserCommand = new CreateUserCommand
{
AccountId = customer.Guid,
};

var user = await mediator.Send(createUserCommand, cancellationToken);

var response = customer.Adapt();

return Ok(response);
}
< /code>
Однако это также кажется мне неправильным, так как я сейчас выполняю бизнес -логику внутри контроллера ... (это также не транзакционно) < /p>
Есть ли способ избежать дублирования кода в приведенном выше случае, это стоимость использования шаблона CQRS или я просто подхожу к всей проблеме неправильно?

Подробнее здесь: https://stackoverflow.com/questions/794 ... th-mediatr
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»