问题
I am using windsor castle as my IoC container, and has run in to a bit of a problem. This is best explained in code, so I´ll give it a try. I have a factory class, that should provide me with implementations of a certain interface:
public interface IObjectCreatorFactory
{
IObjectCreator GetObjectCreator(Type objectType);
}
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
}
Implementation of the factory class could look like this, though I am not sure this is the way to go: public interface 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;
}
}
Now this would work out ok, but if I want my IObjectCreator instance to create child objects using a specific IObjectCreator, i would like to call ObjectCreatorFactory, and this obviously results in a circular reference:
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);
}
This does not work out. What would be the way to go for this scenario, where the created objects are refering back to the factory for child object creators?
回答1:
I would simply move the factory out of the constructors of the various specific object creators, and introduce a method on the IObjectCreator interface instead, responsible for initialising the creators:
public interface IObjectCreator
{
T CreateObject<T>(IDataRow data);
bool SupportsType(Type type);
void Initialize(IObjectCreatorFactory factory);
}
And then just invoke Initialze(this) on each object creator passed into the factory.
In the past I've used custom life cycle stages to take care of automatically invoking "post-construction" setup of components to both avoid circular dependencies and also to take care of other associated concerns (i.e. applying additional component configuration from an external source like a database) - but it's probably overkill for what you need.
来源:https://stackoverflow.com/questions/487786/castle-windsor-how-to-prevent-circular-references-in-factory-created-objects-we