4

I would like to resolve the following with castle windsor:

IEnumerable<Definition<IEntity>>

At the moment I'm only getting an IEnumerable with 1 object which matches the first implementation of IEntity.

I would like an array of

{ Definition<Entity1>, Definition<Entity2>, ... } 

I have a feeling a sub resolver is needed but I have no idea where to start.

Update

var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(
     new CollectionResolver(container.Kernel, true));

container.Register(Component.For(typeof (Definition<>)));

var binDir = HostingEnvironment.MapPath("~/bin");
var assemblyFilter = new AssemblyFilter(binDir);

container.Register(Types.FromAssemblyInDirectory(assemblyFilter)
     .BasedOn<IEntity>()
     .Unless(t => t.IsAbstract || t.IsInterface)
     .WithServiceAllInterfaces()
     .LifestyleTransient());

// This doesn't work!
var items = container.Resolve(typeof(IEnumerable<Definition<IEntity>>));
2
  • Could you add your registration code ? Commented Sep 4, 2013 at 18:09
  • Whereabouts are your implementations for Definition<> ? Commented Sep 12, 2013 at 12:28

1 Answer 1

1

First, I think that you should improve your design a bit. I don't know the actual context, but I believe that your intent is the following:

public interface IEntity
{
}

public class Entity1 : IEntity
{
}

public class Entity2 : IEntity
{
}

public abstract class Definition<TEntity>
    where TEntity : IEntity
{
}

public class Entity1Definition : Definition<Entity1>
{
}

public class Entity2Definition : Definition<Entity2>
{
}

With this design you have the problem that the following code is not valid:

Definition<IEntity> definition = new Entity1Definition();

In order for this to work you should introduce a covariant generic interface for the IEntity type. More on covariance and contravariance you can find here: Covariance and Contravariance in Generics

So I suggest you introduce the following interface:

public interface IDefinition<out TEntity>
    where TEntity : IEntity
{
}

Note the out keyword that marks the interface as covariant. And then derive your Definition<TEntity> from this interface:

public abstract class Definition<TEntity> : IDefinition<TEntity>
    where TEntity : IEntity
{
}

Now, when we have set the design in such way the rest is easy. We can register the components like this:

WindsorContainer container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(
        new CollectionResolver(container.Kernel, true));

container.Register(Types.FromThisAssembly()
        .BasedOn(typeof(IDefinition<>))
        .Unless(t => t.IsAbstract || t.IsInterface)
        .WithServices(typeof(IDefinition<IEntity>))
        .LifestyleTransient());

And then resolve them:

var items = container.ResolveAll(typeof(IDefinition<IEntity>));

Note, that to resolve all instances for a registered service in Windsor you should invoke the ResolveAll method.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.