views:

29

answers:

1

I try to use Ninject to inject a XmlReader. The problem is that it is created by a factory method insted of a constructor. And I can't add a [Inject] to code in the .NET Framework. Now I use following binding to create the XmlReader:

Bind<IXmlReader>()
    .ToMethod(
        x =>
        XmlReader.Create(
                        (string) GetParameter(x, "inputUri"),
                        (XmlReaderSettings) GetParameter(x, "settings")))
    .Named("definition");            


private object GetParameter(IContext context, string name)
{
    var parameters = (List<IParameter>) context.Parameters;
    return (from p in parameters 
            where p.Name == name 
            select p.GetValue(context))
            .FirstOrDefault();
}

And I use it as following:

var reader = _kernel.Get<IXmlReader>("definition",
                                     new Parameter("inputUri", FilePath, false),
                                     new Parameter("settings", settings, false)))

But this code is horrible. Can I rewrite it in any prettier smarter way?

A: 

You're not doing DI, you're doing Service Location.

I dont know your real context but I reckon I'd depend on a Func<string,string,IXmlReader> and do the Bind as follows:-

Bind<Func<string,string,IXmlReader>>()
    .ToMethod( (inputUri,settings) => XmlReader.Create( inputUri,settings))

Then you declare the injected item in your constructor args:

[Named("definition")]<string,string,IXmlReader> createReader

The fun bit is that [Named] above is my own makey upey attribute and you need to do the conditional aspect at bind time. Have a look at the dojo, it will show you how to do that bit.

Ruben Bartelink