Скажем, у меня есть две службы на моем уровне обслуживания, ServiceA
и ServiceB
, каждая с интерфейсом (IServiceA
и IServiceB
соответственно).
Уровень пользовательского интерфейса имеет ссылку только на интерфейсы служб, которые возвращают DTO из своих методов. Конкретные классы обслуживания отвечают за отображение моделей предметной области (EF POCO) в DTO.
ServiceA
принимает зависимость от IServiceB
через внедрение зависимостей с использованием контейнера IoC для вызова некоторых методов этой службы.
При этом возникает пара проблем:
Ненужное / дублированное отображение в DTO и из него просто для вызова метода и / или использования результата.
Тесное связывание вызывающего метода с DTO-контрактами входных параметров и возвращаемого типа вызываемых методов.
Первоначально я думал преобразовать логику во внутренний метод и вызвать его из обеих служб. Однако, поскольку ServiceA
зависит от интерфейса IServiceB
, внутренние методы не отображаются.
Как бы вы справились с этой проблемой?
Дополнительная информация (добавлен пример кода по запросу):
// This is the domain model
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
// This is a dto for the domain model
public class CustomerDto
{
public string Name { get; set; }
}
// Interface for ServiceA
public interface IServiceA
{
void AddCustomer();
}
// ServiceA
public class ServiceA : IServiceA
{
private readonly IServiceB _serviceB;
// ServiceA takes in an IServiceB as a dependency
public ServiceA(IServiceB serviceB)
{
_serviceB = serviceB;
}
public void AddCustomer()
{
var entity = new Customer();
// !! This is the key part !!
// I have to map to a dto in order to call the method on ServiceB.
// This is a VERY simple example but this unnecessary mapping
// keeps cropping up throughout the service layer whenever
// I want to make calls between services.
var dto = Mapper.CreateFrom<CustomerDto>(entity);
_serviceB.DoSomethingElseWithACustomer(dto);
}
}
// Interface for ServiceB
public interface IServiceB
{
void DoSomethingElseWithACustomer(CustomerDto customer);
}
// ServiceB
public class ServiceB : IServiceB
{
public void DoSomethingElseWithACustomer(CustomerDto customer)
{
// Some logic here
}
}