2

I have an open generic interface, which i implement with a non generic class, and i want to inject this class using castle windsor, but am struggling.....

Lets say i have the following interface

public interface IMyInterface<T>
{
    bool DoSomething(T param);
}

And then i have the following class that implements this interface like so

public class MyClass : IMyInterface<string>
{
    public bool DoSomething(string param)
    {
        // Do Something
        return true;
    }
}

I want to be able to resolve the interface using castle like this, so that the injectedObject becomes an instance of MyClass.

WindsorContainer container = new WindsorContainer(new XmlInterpreter(newConfigResource("castle")));
IMyInterface<string> injectedObject = container.Resolve<IMyInterface<string>>();

Is this possible, or have i gone off track slightly? If its possible, how do i set up the castle config section? I have tried using the '1 notation to indicate that the interface is an open generic type, but you get an error if the implementation is not also generic, which in this case it is not.

Any help appreciated

5
  • Are you absolutely certain you want to use XML to register components? Current "best practice" is to register components with the fluent registration API, e.g. container.Register(Component.For<IMyInterface<string>>().ImplementedBy<MyClass>()) Commented Jun 1, 2011 at 9:13
  • @mookid8000 Does that not mean then that if i want to change which concrete implementation of an interface i want to use (say switching between a real and a fake DAO), that i would need to change the code and re-compile? By having it in a castle xml config file i can just change the config and re-start the service or application. Commented Jun 1, 2011 at 9:23
  • Yeah, that's what it means. In my experience, people often tend to think that the ability to switch implementations at runtime is cool, but I have never actually heard of anyone putting it to real use. Commented Jun 1, 2011 at 10:46
  • And it's not like I'm against configuring stuff in XML or anything - you can still have Windsor inject stuff, like e.g. connection strings etc. into repositories, by combining XML with the fluent registration API. Commented Jun 1, 2011 at 10:48
  • Isnt the ability to inject at runtime without the need to re-compile your code one of the main points of dependancy injection though? I find switching between concrete implementations for 3rd party services or Data Access objects and a fake implementation of these is something i do quite often during development and testing, and so i would not want to have to keep changing the code each time and recompiling. Also, it allows people to re-use in a slightly different mode without changing the code. I guess there is an argument to use either approach depending on circumstance Commented Jun 1, 2011 at 12:26

1 Answer 1

4

We use the fluent interface in my team so it's been a while since I've looked at the config file syntax. The basic principle is this: your service is IMyInterface<string> and the implementing type is MyClass. So I think it would be something like this:

<component service="Namespace.IMyInterface`1[[System.String, mscorlib]], AssemblyName"
        type="Namespace.MyClass, AssemblyName" />

You say you get an error. What is the error? I guess it is because you have defined the service as IMyInterface<> without supplying the type parameter. If you want to do that, as your question implies, the implementing type must also be generic:

<component service="Namespace.IMyInterface`1, AssemblyName"
        type="Namespace.MyGenericClass`1, AssemblyName" />

Note that you can register both components. If you do that, resolving IMyInterface<string> will get you an instance of MyClass, while resolving IMyInterface<AnyOtherType> will get you an instance of MyGenericClass<AnyOtherType>.

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

1 Comment

I have just re-tried this and have got it working. I had tried it using the '1 notation, and as you say you get an error if the implementing type isnt generic. I had also tried the first example above, HOWEVER i had not specified the Assembly name of generic type (in this case mscorlib). Adding this in solves the problem Thanks..

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.