Один зі способів покращення архітектури системи — це зменшення зв'язності між компонентами. Цього можна добитись розділивши класи по окремим пакетам та контролювати залежності між ними. Також можна дотримуватись правил залежності. Наприклад, класи бізнес-логіки не повинні викликати класи логіки представлення.
При такому підході класи рівня аплікації хоч і використовують для роботи інтерфейси, та все одно вони прив'язані до модуля інфраструктури. Для того, щоб уникнути цієї залежності скористаємось принципом інверсії залежностей, та "розвернемо" стрілки залежностей в іншу сторону. Варто винести всі залежності в інтерфейси, які будуть використовувати класи модуля аплікації, а їх реалізацію помістити в окремі пакети.
Таким чином модулі вищого рівня залежать від абстракцій реалізованих в модулях нижчого рівня.
Помістимо в один модуль класи та залежності необхідні їм для роботи у вигляді інтерфейсів.
namespace Application
{
internal class WeatherAppService
{
private ITimeService _timeService;
public WeatherAppService(ITimeService timeService)
{
_timeService = timeService;
}
public WeatherForecast GetWeatherForecast()
{
var currentTime = _timeService.GetCurrentTime();
return new WeatherForecast
{
Time = currentTime,
TemperatureC = new Random().Next(-20, 55),
};
}
}
public interface ITimeService
{
DateTime GetCurrentTime();
}
}
Тоді реалізуємо інтерфейси в окремому модулі. Який міститиме прив'язку до конкретних технологій.
namespace Infrastructure
{
public class TimeService : ITimeService
{
public DateTime GetCurrentTime()
{
return DateTime.Now;
}
}
}
Тепер класи аплікацій можна легко тестувати, підміняти реалізацію, незалежно розгортати тощо.