Используйте фабричный метод в Ninject, к которому я не могу добавить атрибут

Я пытаюсь использовать Ninject для внедрения XmlReader. Проблема заключается в том, что он создается методом фабрики вместо конструктора. И я не могу добавить [Inject] кодировать в.NET Framework. Теперь я использую следующую привязку для создания 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();
}

И я использую это следующим образом:

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

Но этот код ужасен. Могу ли я переписать это каким-нибудь красивее, умнее?

1 ответ

Решение

Вы не делаете DI, вы делаете Service Location.

Я не знаю ваш реальный контекст, но я думаю, я бы зависел от Func<string,string,IXmlReader> и сделайте Привязку следующим образом:

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

Затем вы объявляете внедренный элемент в аргументе конструктора:

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

Самое интересное, что [Named] выше - мой собственный атрибут makey upey, и вам нужно выполнить условный аспект во время привязки. Посмотрите на додзё, оно покажет вам, как это сделать. Там есть встроенный NamedAttribute (и был целую вечность, понятия не имею, о чем я думал).

Если что-то вроде внедрения фабрики полезно в вашем случае, следующая вещь, на которую стоит обратить внимание, это Ninject.Extensions.Factory. Он обрабатывает большинство этих видов производственных требований в чистом виде.

Другие вопросы по тегам