Проблема с именами конструктора аргументов и выражений, что выражение действительно только/завершенным, когда она охватывает все параметры конструктора ,Теперь я полагаю, вы хотите, чтобы ввести несколько параметров (есть Ninject обращаться с ними) и в течение одного или двух конкретных параметров, которые вы хотите передать значение, скажем, это выглядит следующим образом:
public interface IFoo { }
public class Foo : IFoo
{
public Foo(IServiceOne one, IServiceTwo two, string parameter) {...}
}
Ninject поддерживает CTOR выражения, но только для переплетов, и они работают так:
IBindingRoot.Bind<IFoo>().ToConstructor(x =>
new Foo(x.Inject<IServiceOne>(), x.Inject<IServiceTwo>(), "staticArgument");
поэтому вместо того, только с указанием «staticArgument», который вас интересует, вы также должны указать IServiceOne
и IServiceTwo
. Что, если конструктор изменится? Ну и звонок нужно адаптировать! Много работы за прохождение простого простого параметра.
Теперь, если вы все еще хотите сделать это, я хотел бы предложить, имея взгляд на ToConstructor
кода и создания аналогичного расширения для Get
вызова, который будет переводить некоторые вызов
IResolutionRoot.Get<IFoo>(x =>
new Foo(
x.Ignore<IServiceOne>(),
x.Ignore<IServiceTwo>(),
x.UseValue("mystring"));
в
IResolutionRoot.Get<IFoo>(new ConstructorArgument("parameter", "mystring"));
Однако я бы посоветовал пойти с ответом @Sergey Brunov и использовать Ninject.Extensions.Factory. Теперь я думаю, что вы скажете, что это нехорошо, потому что вам все равно придется указывать имя параметра, которое не является рефакторингом и суетным (без завершения кода ...).
Однако есть решение проблемы: вместо использования аргумента конструктора, который «соответствует» имени аргумента, вы можете использовать аргумент соответствия типа. Хорошо, есть улов. Если у вас есть несколько аргументов одного типа, ... это не сработает. Но я думаю, что это редко бывает, и вы все еще можете ввести контейнер данных класса для ее решения:
public class FooArguments
{
string Argument1 { get; set; }
string Argument2 { get; set; }
}
Теперь, как вы можете использовать согласование типа? Там два способа:
- Используйте
Func<string, IFoo>
завод. Просто введите Func<string, IFoo>
в то место, где вы хотите создать, и IFoo
.
- Расширение заводского расширения. Да, вы слышали правду ;-) На самом деле это не так сложно. Вы «просто» нужно реализовать пользовательские
IInstanceProvider
(также см http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/), так что вы можете что-то вроде:
public interface IFooFactory
{
IFoo Create([MatchByType]string someParam, string matchByName);
}
(==> использовать атрибут сказать расширение фабрики, как передать параметр в запрос Get<IFoo>
).
Это работает конструктор? В моем тесте я могу видеть только свойства класса? –