Виндзорский замок:Как предотвратить циклические ссылки в объектах, созданных на фабрике, если созданные объекты ссылаются обратно на фабрику
-
20-08-2019 - |
Вопрос
Я использую виндзорский замок в качестве своего контейнера IoC и столкнулся с небольшой проблемой.Лучше всего это объясняется в коде, так что я попробую.У меня есть фабричный класс, который должен предоставить мне реализации определенного интерфейса:
public interface IObjectCreatorFactory
{
IObjectCreator GetObjectCreator(Type objectType);
}
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
}
Реализация класса factory могла бы выглядеть следующим образом, хотя я не уверен, что это правильный путь:ObjectCreatorFactory с открытым интерфейсом:IObjectCreatorFactory { Множество конкретных создателей;IObjectCreator defaultCreator IObjectCreator defaultCreator;
public ObjectCreatorFactory(IEnumerable<IObjectCreator> specificCreators, IObjectCreator defaultCreator)
{
this.specificCreators= specificCreators;
this.defaultCreator= defaultCreator;
}
public IObjectCreator GetObjectCreator(Type objectType)
{
foreach (IObjectCreator creator in specificCreators)
{
if (creator.SupportsType(objectType))
{
return creator;
}
}
return defaultCreator;
}
}
Теперь это сработало бы нормально, но если я хочу, чтобы мой экземпляр IObjectCreator создавал дочерние объекты с использованием определенного IObjectCreator , я хотел бы вызвать ObjectCreatorFactory , и это, очевидно, приводит к циклической ссылке:
public void SpecificObjectCreator:IObjectCreator
{
IObjectCreatorFactory objCreatorFactory;
public SpecificObjectCreator(IObjectCreatorFactory objCreatorFactory)
{
this.objCreatorFactory = objCreatorFactory;
}
T CreateObject<T>(IDataRow data)
{
T obj = new T;
ChildObject childObject = objCreatorFactory.GetObjectCreator(typeof(ChildObject)).CreateObject<ChildObject>(data);
.......
}
bool SupportsType(Type type);
}
Из этого ничего не выйдет.Каков был бы путь для этого сценария, когда созданные объекты ссылаются обратно на фабрику для создателей дочерних объектов?
Решение
Я бы просто убрал фабрику из конструкторов различных конкретных создателей объектов и вместо этого ввел метод в интерфейсе IObjectCreator, отвечающий за инициализацию создателей:
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
void Initialize(IObjectCreatorFactory factory);
}
А затем просто вызовите Initialze(this) для каждого объекта, переданного создателем на фабрику.
В прошлом я использовал пользовательские этапы жизненного цикла, чтобы позаботиться об автоматическом вызове настройки компонентов "после конструирования", чтобы избежать циклических зависимостей, а также позаботиться о других связанных проблемах (т.е.применение дополнительной конфигурации компонента из внешнего источника, такого как база данных) - но это, вероятно, излишество для того, что вам нужно.