views:

342

answers:

2

Hi all.

I have a common datacontainer interface IDataContainer

I use it for different types of T IPerson, ISuperMan etc

In castle i regsiter it with

container.AddComponentWithLifestyle<IDataContainer<IPerson>, DataContainer<Person>>(LifestyleType.Transient);
container.AddComponentWithLifestyle<IDataContainer<ISuperMan>, DataContainer<SuperMan>>(LifestyleType.Transient);

at runtime castle creates the dependency with eg.

IDataContainer<IPerson> test = container.GetService<IDataContainer<IPerson>>();

but it fails with an unable to cast...the classes implements the interface and namespaces are correct etc.

The call

IPerson test = container.GetService<IPerson>();

Works (with the registration of <IPerson,Person>)

Cant castle resolve an interface<T> or ?

A: 

This has nothing to do with Windsor. You get a casting error because C# 2.0 and 3.0 do not support generics covariance. You're probably making DataContainer<T> implement IDataContainer<T>, which means that DataContainer<Person> implements IDataContainer<Person> and not IDataContainer<IPerson> which is what you're requesting from the container.

Mauricio Scheffer
+1  A: 

So this is way late, but I think I know what you're trying to do here. I'm able to get this to pass:

IDataContainer<IPerson> test = container.GetService<IDataContainer<IPerson>>();

By registering components like this:

public class IoC
{
    public static void SetUp()
    {
        container = new WindsorContainer();
        container.AddComponent<IPerson, Person>();
        //container.AddComponentWithLifestyle<IDataContainer<IPerson>, DataContainer<Person>>(LifestyleType.Transient);
        //container.AddComponentWithLifestyle<IDataContainer<ISuperMan>, DataContainer<SuperMan>>(LifestyleType.Transient);
        container.AddComponentWithLifestyle("DataContainers", typeof(IDataContainer<>), typeof(DataContainer<>), LifestyleType.Transient);
    }

    public void TestOne()
    {
        SetUp();
        var test = container.GetService<IDataContainer<IPerson>>();
        Assert.That(test, Is.Not.Null);
    }

    public void TestTwo()
    {
        SetUp();
        var test = container.GetService<IPerson>();
        Assert.That(test, Is.Not.Null);
    }
}

internal interface IDataContainer<T> { }
internal class DataContainer<T> : IDataContainer<T> { }

internal interface IPerson { }
class Person : IPerson { }

internal interface ISuperMan { }
class SuperMan : ISuperMan { }

The two lines that are commented out are the two lines that exist in the question.

Chris Missal