Используйте фабричный метод в 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. Он обрабатывает большинство этих видов производственных требований в чистом виде.