D3athSpank
D3athSpank

Reputation: 169

Resolving object with List of different implementations as constructor parameter using Castle Windsor

I have the following constructor:

public DataImporterService(IList<IDataValidator> dataValidators,     IList<IDataComparer> dataComparers, IList<IDataStorage> dataStorages)
        {
            _dataValidators = dataValidators;
            _dataComparers = dataComparers;
            _dataStorages = dataStorages;
        }

and this is my registration:

Component.For<IDataComparer>().ImplementedBy<PlanOfRecordComparer>().Named("planOfRecordComparer"),
                Component.For<IDataComparer>().ImplementedBy<PlanOfExecutionComparer>().Named("planOfExecutionComparer"),
                 Component.For<IDataComparer>().ImplementedBy<BomComparer>().Named("bomComparer"),
                Component.For<IDataStorage>().ImplementedBy<PlanOfRecordStorage>().Named("planOfRecordStorage"),
                Component.For<IDataStorage>().ImplementedBy<PlanOfExecutionStorage>().Named("planOfExecutionStorage"),
                Component.For<IDataValidator>().ImplementedBy<PlanOfExecutionValidator>().Named("planOfExecutionValidator"),
                Component.For<IDataValidator>().ImplementedBy<PlanOfRecordValidator>().Named("planOfRecordValidator"),
                Component.For<IDataValidator>().ImplementedBy<BomValidator>().Named("bomValidator")

but is it possible to register the components in another way not needing to specify each and every implementation of IDataComparer,IDataValidator and IDataStorage? Like in a more generic way?

Upvotes: 0

Views: 323

Answers (2)

D3athSpank
D3athSpank

Reputation: 169

Ok this is how i made it work:

First of I used a collectionresolver:

 container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));

To register all classes that implements IDataComparer , IDataStorage , IDataValidator

Classes.FromThisAssembly().Where(x => x.Name.EndsWith("Validator")).WithServiceFirstInterface(),
Classes.FromThisAssembly().Where(x => x.Name.EndsWith("Comparer")).WithServiceFirstInterface(),
Classes.FromThisAssembly().Where(x=>x.Name.EndsWith("Storage")).WithServiceFirstInterface()

Then I was able to resolve my class:

public DataImporterService(IDataValidator[] dataValidators, IDataComparer[] dataComparers, IDataStorage[] dataStorages)
        { }

So when Castle Windsor tries to resovle the DataImporterService it grabs all classes that implements the injected interfaces, construct an array, put them in the array and provide the array as the value for the dependency.

This is provided in the documentation here

Upvotes: 1

Mark Seemann
Mark Seemann

Reputation: 233150

Are you looking for Auto-registration (AKA convention-based configuration)?

If so, based off the example in section 10.1.2 of my book, you should be able to do something like

container.Register(AllTypes
    .FromAssemblyContaining<PlanOfExecutionComparer>()
    .BasedOn<IDataComparer>());

Upvotes: 1

Related Questions