views:

59

answers:

1

Using Castle Windsor, I want to configure a generic service with a type parameter; and have it implemented by a known concrete type that implements the service with a specific type as the generic parameter. Expressed as a unit test, I would like to get the following to work:

[TestClass]
public class WindsorTests
{
    [TestMethod]
    public void ResolveGenericEntity_Test()
    {
        WindsorContainer container = ConfigureContainer();
        IEntity<string> entity = container.Resolve<IEntity<string>>();
        Assert.IsNotNull(entity);
    }

    private WindsorContainer ConfigureContainer()
    {
        WindsorContainer container = new WindsorContainer();
        container.AddComponent("entity", typeof(IEntity<>), typeof(ConcreteEntity));
        return container;
    }
}

public interface IEntity<T> { }

public class ConcreteEntity : IEntity<string> {}

This test fails with the following exception:

System.InvalidOperationException: WindsorGenericsTest.ConcreteEntity is not a GenericTypeDefinition. MakeGenericType may only be called on a type for which Type.IsGenericTypeDefinition is true.

Now, I have found a post here describing the same problem. The poster describes how this can be resolved by changing the DefaultGenericHandler.ResolveCore method. However, I don't feel like changing the Castle code itself and running on a custom build.

Does anyone know how I can resolve this problem without modifying the Castle Windsor source code ? I am happy to implement a facility to support this, if that is what is needed.

+1  A: 

Will it work if you change the line in ConfigureContainer to this?

container.AddComponent("entity", typeof(IEntity<string>), typeof(ConcreteEntity));
Daniel Plaisted
Yes that works, but it is not what I need (the concrete usage is in a rather complicated graph of injected objects, my code sample is the shortest possible that reproduces the problem).
driis
So what do you need? This answer is just the right solution to your problem from the question - your `ConcreteEntity` implements `IEntity<string>` not `IEntity<>` so you should register it as such
Krzysztof Koźmic