Универсальный декоратор Autofac для разных интерфейсов на одной основеC#

Место общения программистов C#
Ответить
Anonymous
 Универсальный декоратор Autofac для разных интерфейсов на одной основе

Сообщение Anonymous »

У меня есть приложение, состоящее из двух уровней: WebApi и Domain.
WebApi имеет контроллеры, которые вызывают бизнес-логику в домене через интерфейс IInteractor.

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

public interface IInteractor
{
Task Execute(TRequestModel model);
}
Обязанности действия контроллера:
  • принять веб-запрос
  • преобразовать его в модель запроса
  • вызвать интерактор через интерфейс IInteractor
  • преобразовать модель ответа интерактора в DTO
    и вернуть клиенту
Вот пример такого действия контроллера:

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

[HttpGet(Name = nameof(GetFoobar))]
public async Task GetFoobar(
[FromServices] IInteractor getFoobar,
[FromQuery] string candidate
)
{
var requestModel = new GetFoobarRequestModel(candidate);
var result = await getFoobar.Execute(requestModel);

return result
.Match(
foobar => Ok(foobar),
notFound => NotFound());
}
Конкретный интерактор выглядит так:

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

public class GetFoobarInteractor : IInteractor
{ ... }
Регистрация DI для интеракторов осуществляется в соответствии с соглашениями.

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

builder.RegisterAssemblyTypes(assemblyThatContainsInteractors)
.AsClosedTypesOf(typeof(IInteractor))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
И есть декоратор для ведения журнала, который регистрируется следующим образом:

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

builder.RegisterGenericDecorator(typeof(InteractorLoggingDecorator), typeof(IInteractor));
Пока это работает довольно хорошо.

Но внедрение закрытого универсального интерфейса, например IInteractor немного громоздкий, так как его трудно читать.

Мне хотелось бы иметь более простой интерфейс, который усиливает бизнес-задачи .

Этого можно добиться путем введения интерфейса для каждого интерактора.

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

public interface IGetFoobar : IInteractor;
Затем конкретный интерактор реализует новый, более компактный интерфейс:

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

public class GetFoobarInteractor : IGetFoobar
{ ... }
Благодаря этому действие контроллера может избавиться от неуклюжего интерфейса и стать более понятным:

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

[HttpGet(Name = nameof(GetFoobar))]
public async Task GetFoobar(
[FromServices] IGetFoobar getFoobar,
[FromQuery] string candidate
)
{ ... }
Однако сейчас возникла проблема.

InteractorLoggingDecorator больше не вызывается.

Я думаю, что это это из-за .AsImplementedInterfaces(), поскольку он регистрирует конкретный интерактор для обоих интерфейсов а декоратор работает только для второго.
Как зарегистрировать InteractorLoggingDecorator для всех интерфейсов по соглашениям?

Подробнее здесь: https://stackoverflow.com/questions/790 ... same-basis
Ответить

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

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

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

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

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