Расположение сервисов в доменных службах и службах приложения в луковой архитектуре
У меня есть бот, вот его основной функционал: Пользователь оплачивает подписку, с помощью нее добавляет Инстаграм и авторизует его. Далее он создает работу (сущность Work), заполняет ее необходимыми данными (сообщение, откуда брать получателей) и запускает работу. Эта работа в фоне получит пользователей в соответствии с типом работы и отправит им сообщения.
Я хочу реализовать луковую архитектуру и не совсем понимаю, куда располагать следующие службы. Мое предположение:
Интерфейс платежной системы должен быть в доменных службах, а реализация должна быть в инфраструктуре. Так же и с инстаграмом - его основная задача это авторизация и отправка сообщений. Оба эти интерфейса должны быть на уровне доменных служб, но с реализацией в инфраструктуре. Интерфейс запуска задач тоже должен находиться в доменных службах с реализацией в инфраструктуре, так как основная задача сущности Work это выполнять в фоне какие-либо действия. А вот сама служба обработки сущности Work должна иметь не только интерфейс, но и реализацию на уровне доменных служб.
Варианты использования к примеру будут: создавать работу, добавлять в нее инстаграмы и запускать.
Вот примеры интерфейсов:
public interface IWorkScheduler
{
Task StartWorkNowAsync(Work work);
Task ScheduleWorkAsync(Work work, DateTimeOffset dateTimeOffset);
Task CancelWorkAsync(Work work);
}
public interface IBackgroundJobService //Служба, в которой и происходит выполнение всех фоновых задач, реализована в доменных службах
{
Task ProcessingMailingAsync(Work workDto, CancellationToken token);
Task<List<Work>> ProcessingDivideWorkAsync(Work workDto, CancellationToken token);
Task SaveAfterContinuedAsync(Work workDto);
}
public interface IInstagramUsersGetterService
{
Task<List<long>> GetUsersAsync(Work workDto, CancellationToken token);
}
public interface IPaymentSystem
{
Task<Payment> CreatePaymentAsync(User user, int countSubscribes);
Task<Payment> GetPaymentInfoAsync(string id);
}
public interface ITelegramService
{
public Task SendMessageAsync(long id, string message)
}
public class Work //Сущность Work, в нее будут добавлены некоторые бизнес правила
{
public int Id { get; set; }
public List<InstagramLite> Instagrams { get; set; } = new();
public List<long> InstagramPks { get; set; } = new();
public string? Message { get; set; }
public string? JobId { get; set; }
public string? Hashtag { get; set; }
public WorkUsersType UsersType { get; set; }
public WorkType Type { get; set; }
public DateTime StartTime { get; set; }
public bool IsCompleted { get; set; }
public string? ErrorMessage { get; set; }
public int CountErrors { get; set; }
public int CountSuccess { get; set; }
}
public class Instagram //Сущность Instagram
{
public int Id { get; set; }
public string Username { get; set; } = null!;
public string Password { get; set; } = null!;
public string? StateData { get; set; }
public string? TwoFactorLoginInfo { get; set; }
public string? ChallengeLoginInfo { get; set; }
public bool IsActive { get; set; }
public UserLite? User { get; set; }
public Proxy? Proxy { get; set; }
public void SetProxy(Proxy proxy) => Proxy = proxy;
}