Castelo de Windsor: Como evitar referências circulares em objetos criados na fábrica foram os objetos criados remete para a fábrica
-
20-08-2019 - |
Pergunta
Eu estou usando o Castelo de Windsor como meu contêiner IoC, e foi executado em um pouco de um problema. Isto é melhor explicado no código, então eu vou dar-lhe uma tentativa. Eu tenho uma classe de fábrica, que deve fornecer-me com implementações de uma determinada interface:
public interface IObjectCreatorFactory
{
IObjectCreator GetObjectCreator(Type objectType);
}
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
}
A implementação da classe de fábrica poderia ser assim, embora eu não estou certo de que este é o caminho a percorrer: ObjectCreatorFactory interface pública: IObjectCreatorFactory { specificCreators IEnumerable; 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;
}
}
Agora, isso iria funcionar ok, mas se eu quero o meu exemplo IObjectCreator para criar objetos filho usando um específico IObjectCreator, eu gostaria de chamar ObjectCreatorFactory, e isso, obviamente, resulta em uma referência circular:
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);
}
Esta não funciona. Qual seria o caminho a percorrer para este cenário, onde os objetos criados são referindo-se de volta à fábrica para os criadores de objetos filho?
Solução
Eu simplesmente mover a fábrica fora dos construtores dos vários criadores objeto específico, e introduzir um método na interface IObjectCreator vez, responsável por inicializar os criadores:
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
void Initialize(IObjectCreatorFactory factory);
}
E depois é só invocar Initialze (this) em cada criador objeto passado para a fábrica.
No passado, eu usei estágios do ciclo de vida personalizado para cuidar de invocar automaticamente a configuração "pós-construção" de componentes para ambas as dependências circulares evitar e também para cuidar de outras preocupações associadas (ou seja, a aplicação de configuração do componente adicional de um fonte externa, como um banco de dados.) - mas é provavelmente um exagero para o que você precisa