Лучше всего составлять полные графы объектов с самого начала.Ввод значений null
следует предотвратить, поскольку это усложняет класс потребления.
Однако в вашем случае кажется, что Socket
не является "реальным" компонентом, а скорее во время выполнения.данные .Как описано здесь , вы должны запретить вставку данных времени выполнения в граф объектов во время построения.
В этой статье предлагаются два решения для решения этой проблемы, но есть и другие решения.Однако, как вы уже упоминали, абстрактные фабрики, как правило, не являются хорошим решением, а в этом посте в более общем смысле описывает проблему с абстрактными фабриками.В главе 6.2 этой книги даже более подробно рассказывается о проблеме с абстрактными фабриками с точки зрения DI.
Решением, приведенным в сообщении в блоге, является использование «контекста»абстракция.В вашем случае, например, интерфейс SocketContext
, который позволяет вам получить значение времени выполнения Socket
потребителем после вызова методов этого потребителя и, таким образом, после графика объекта потребителя.Например:
public interface SocketContext
{
Socket get_CurrentSocket();
}
Другой вариант - использовать прокси-класс, который либо скрывает реальный Socket
или реальный SocketManager
(в зависимости от того, на каком уровне вы можете разместить прокси).Это позволяет потребителю не знать, что некоторая часть данных времени выполнения должна быть инициализирована под прикрытием и что это может быть выполнено лениво после первого вызова.Например:
public class SocketManagerLazyProxy : SocketManager
{
private SocketManager mananger;
public void DoSomething()
{
if (manager == null) manager = new RealSocketManager(new Socket());
manager.DoSomething();
}
}
Другой вариант - установить значение Socket
, используя свойство Injection после построения графа объектов.Это позволяет вам построить граф объектов намного раньше и установить значение времени выполнения при поступлении запроса, установив его при поступлении запроса:
void HandleRequest(RequestData data)
{
SocketManager manager = GetSocketManagerForThisRequest();
manager.Socket = new Socket();
Handler handler = GetHandler(data.Name);
handler.Handle(data);
}