Ответ 1
В зависимости от ваших потребностей вы можете выбрать один из двух маршрутов.
1. Подключите интерфейс непосредственно к вашим конкретным классам
Это самый простой вариант, но во многих случаях вполне приемлемый. Хотя у вас может быть Доменная модель с большим количеством интерфейсов и использованием DI, пользовательский интерфейс представляет собой корень композиции графов объектов, и вы можете просто подключить здесь свой конкретный класс, включая требуемый параметр номера порта.
Плюс в том, что этот подход прост и легок для понимания и реализации.
Недостатком является то, что вы получаете меньше гибкости. Вы не сможете произвольно заменить одну реализацию другой (но опять же, вам может не потребоваться такая гибкость).
Даже если пользовательский интерфейс привязан к конкретной реализации, это не означает, что модель домена сама по себе не будет использоваться в других приложениях.
2. Добавьте абстрактную фабрику
Другой вариант - добавить еще один слой косвенности. Вместо того чтобы ваш пользовательский интерфейс создавал класс напрямую, он мог бы использовать абстрактную фабрику для создания экземпляра.
Заводской метод Create
может принимать номер порта в качестве входного, поэтому эта абстракция лучше всего относится к подуровню пользовательского интерфейса.
public abstract class MyFactory
{
public abstract IMyInterface Create(int portNumber);
}
После этого ваш DI-контейнер может подключить реализацию этой фабрики, которая использует номер порта и передает его в качестве аргумента конструктора для вашей реальной реализации. Другие реализации фабрики могут просто игнорировать параметр.
Преимущество этого подхода заключается в том, что вы не загрязняете свой API (или ваши конкретные реализации), и у вас все еще есть гибкость, которую дает вам программирование для интерфейсов.
Недостатком является то, что он добавляет еще один слой косвенности.