Castle Windsor: come prevenire riferimenti circolari negli oggetti creati dalla fabbrica dove gli oggetti creati rimandano alla fabbrica
-
20-08-2019 - |
Domanda
Sto usando Windsor Castle come mio contenitore IoC e ho riscontrato un po 'di problemi. Questo è meglio spiegato nel codice, quindi io & # 180; lo proverò. Ho una classe di fabbrica, che dovrebbe fornirmi implementazioni di una certa interfaccia:
public interface IObjectCreatorFactory
{
IObjectCreator GetObjectCreator(Type objectType);
}
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
}
L'implementazione della classe factory potrebbe apparire così, anche se non sono sicuro che sia la strada da percorrere: interfaccia pubblica ObjectCreatorFactory: IObjectCreatorFactory { IEnumerable specificCreators; 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;
}
}
Ora questo funzionerebbe bene, ma se voglio che la mia istanza IObjectCreator crei oggetti figlio usando uno IObjectCreator specifico, vorrei chiamare ObjectCreatorFactory e questo ovviamente porta a un riferimento circolare:
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);
}
Questo non funziona. Quale sarebbe la strada da percorrere per questo scenario, in cui gli oggetti creati rimandano alla fabbrica per i creatori di oggetti figlio?
Soluzione
Sposterei semplicemente la fabbrica fuori dai costruttori dei vari creatori di oggetti specifici e introdurrei un metodo sull'interfaccia IObjectCreator, responsabile dell'inizializzazione dei creatori:
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
void Initialize(IObjectCreatorFactory factory);
}
E poi invoca Initialze (questo) su ciascun creatore di oggetti passato in fabbrica.
In passato ho usato fasi del ciclo di vita personalizzate per occuparmi di invocare automaticamente " post-costruzione " installazione di componenti sia per evitare dipendenze circolari sia per prendersi cura di altri problemi associati (vale a dire applicare la configurazione di componenti aggiuntivi da una fonte esterna come un database) - ma probabilmente è eccessivo per quello che ti serve.