Создание экземпляра с помощью Ninject с дополнительными параметрами в конструкторе
Я решил начать использовать Ninject и столкнуться с проблемой. Скажем, у меня есть следующий сценарий.
У меня есть IService
интерфейс и 2 класса, реализующие этот интерфейс. А также у меня есть класс, который имеет конструктор getting IService и int. Как я могу создать экземпляр этого класса с помощью Ninject (я не хочу подключать этот int, я хочу передавать его каждый раз, когда я получаю экземпляр)?
вот некоторый код, иллюстрирующий ситуацию:
interface IService
{
void Func();
}
class StandardService : IService
{
public void Func()
{
Console.WriteLine("Standard");
}
}
class AlternativeService : IService
{
public void Func()
{
Console.WriteLine("Alternative");
}
}
class MyClass
{
public MyClass(IService service, int i)
{
this.service = service;
}
public void Func()
{
service.Func();
}
IService service = null;
}
class Program
{
static void Main(string[] args)
{
IKernel kernel = new StandardKernel(new InlineModule(
x => x.Bind<IService>().To<AlternativeService>(),
x => x.Bind<MyClass>().ToSelf()));
IService service = kernel.Get<IService>();
MyClass m = kernel.Get<MyClass>();
m.Func();
}
}
1 ответ:
The
With.ConstructorArgument
существовал в 1.0 для этой цели. В версии 2.0 синтаксис немного изменился:- С.Параметры.ConstructorArgument с ninject 2.0посмотреть ввести значение в введенную зависимость для получения более подробной информации и примеров того, как использовать контекст, поставщиков и аргументы, чтобы передать такие вещи более правильно.
EDIT: поскольку Стивен решил притвориться, что мой комментарий не имеет отношения к делу, мне лучше прояснить, что я говорю с некоторыми примерами (для 2.0):
MyClass m = kernel.Get<MyClass>( new ConstructorArgument( "i", 2) );
что для моих глаз очень ясно и точно говорит о том, что происходит.
если вы находитесь в положении, когда вы можете определить параметр более глобальным способом, вы можете зарегистрировать поставщика и сделать это следующим образом:
class MyClassProvider : SimpleProvider<MyClass> { protected override MyClass CreateInstance( IContext context ) { return new MyClass( context.Kernel.Get<IService>(), CalculateINow() ); } }
и зарегистрировать его так:
x => x.Bind<MyClass>().ToProvider( new MyClassProvider() )
важно!
CalculateINow()
бит-это то, где вы бы поместили свою логику, как в первом ответе.или сделать его более сложным, как это:
class MyClassProviderCustom : SimpleProvider<MyClass> { readonly Func<int> _calculateINow; public MyClassProviderCustom( Func<int> calculateINow ) { _calculateINow = calculateINow; } protected override MyClass CreateInstance( IContext context ) { return new MyClass( context.Kernel.Get<IService>(), _calculateINow() ); } }
который вы зарегистрировали бы так:
x => x.Bind<MyClass>().ToProvider( new MyClassProviderCustom( ( ) => new Random( ).Next( 9 ) ) )
обновление: новые механизмы, которые показывают гораздо более совершенные модели с меньшим шаблоном, чем выше, воплощены в