Windsor capture allows array with open common interface and interface

I would like to solve the following with a windsor lock:

IEnumerable<Definition<IEntity>> 

At the moment, I only get IEnumerable with 1 object that corresponds to the first implementation of IEntity.

I need an array

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

I have a feeling that I need an auxiliary resolver, but I don’t know 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>>)); 
+4
source share
1 answer

First of all, I think you should improve your design a bit. I do not know the actual context, but I believe that your intention is this:

 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> { } 

There is a problem in this design that the following code is invalid:

 Definition<IEntity> definition = new Entity1Definition(); 

For this to work, you must introduce a covariant generic interface for the IEntity type. You can find more about covariance and contravariance here: Covariance and contravariance in generics

Therefore, I suggest you introduce the following interface:

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

Note the out keyword, which marks the interface as covariant. And then derive your <TEntity> definition from this interface:

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

Now that we have created the design this way, the rest is easy. We can register the components as follows:

 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 enable them:

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

Note that you must call the ResolveAll method to resolve all instances of the registered service in Windsor.

+1
source

Source: https://habr.com/ru/post/1500550/


All Articles