Reputation: 7522
How do I convert this to Constructor Injection in Castle Windsor (it seems to be related to this question Windsor Castle resolving multiple dependencies with same interface but I think my example is a bit more complicated?).
public class ImageUpdaters : List<IImageUpdater>
{
public ImageUpdaters()
{
Add(new ApplicationTileBackImageUpdater(ApplicationUnits.Imperial));
Add(new ApplicationTileBackImageUpdater(ApplicationUnits.Metric));
Add(new ApplicationTileFrontImageUpdater(ApplicationUnits.Imperial));
Add(new ApplicationTileFrontImageUpdater(ApplicationUnits.Metric));
...
}
}
It's not quite as simple as just passing in a list of all the implementations of IImageUpdater since most are parameterised. I have another slightly more complicated example where some objects need to share the same instance
public DataProcessors()
{
var snowReportRetriever = new CachingDataRetriever(new UriRetriever("http://.."));
var notificationSender = new NotificationSender(new MessageGenerator(new SQLDataReader()), new MessageSender());
var snowDepthProcessor = new DataProcessor<SnowDepthModel>(
"SnowDepthFact"
, snowReportRetriever
, new SnowDepthParser()
, new SnowDepthModelPersistor()
, new SnowDepthModelNotifier(notificationSender)
, new SQLDataReader());
var runsOfTheDayProcessor = new DataProcessor<ModelList<RunsOfTheDayModel>>
(
"RunsOfTheDayFact"
, snowReportRetriever
, new RunsOfTheDayParser()
, new RunsOfTheDayModelPersistor()
, new SQLDataReader());
...
EDIT: I'm getting somewhere, I can register the individual ImageUpdaters and the List but the list is empty so my assertion fails?
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel, true));
container.Register(
Component.For<IList<IImageUpdater>>()
.ImplementedBy<List<IImageUpdater>>()
);
container.Register(
Component.For<IImageUpdater>()
.ImplementedBy<ApplicationTileFrontImageUpdater>()
.DependsOn(Property.ForKey<ApplicationUnits>().Eq(ApplicationUnits.Metric))
.Named("ApplicationTileFrontImageUpdaterMetric")
);
...
var imageUpdaters = container.Resolve<IList<IImageUpdater>>();
Assert.AreEqual(13,imageUpdaters.Count);
Upvotes: 3
Views: 1655
Reputation: 7522
I've worked it out, if anyone has any feedback on whether this is a good/best solution I'd be very interested
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel, true));
container.Register(
Component.For<IImageUpdater>()
.ImplementedBy<ApplicationTileFrontImageUpdater>()
.DependsOn(Property.ForKey<ApplicationUnits>().Eq(ApplicationUnits.Metric))
.Named("ApplicationTileFrontImageUpdaterMetric")
);
container.Register(
Component.For<IImageUpdater>()
.ImplementedBy<ApplicationTileFrontImageUpdater>()
.DependsOn(Property.ForKey<ApplicationUnits>().Eq(ApplicationUnits.Imperial))
.Named("ApplicationTileFrontImageUpdaterImperial")
);
....
container.Register(
Component.For<TestImageUpdaterClass>()
.ImplementedBy<TestImageUpdaterClass>()
);
var tiuc = container.Resolve<TestImageUpdaterClass>();
Assert.AreEqual(13, tiuc.ImageUpdaters.Count);
Then for test purposes a class that consumes a list of IImageUpdaters
public class TestImageUpdaterClass
{
public IList<IImageUpdater> ImageUpdaters { get; set; }
public TestImageUpdaterClass(IList<IImageUpdater> imageUpdaters)
{
ImageUpdaters = imageUpdaters;
}
}
Upvotes: 4