2012-06-27 2 views
4

Используя расширение Ninject Factory, вы можете автоматически генерировать фабрики и позволить фабрике передавать параметры конструктору класса. Следующий тест проходит:Получите расширение фабрики ninject, чтобы разрешить параметры фабрики для зависимостей.

public interface IBar 
{ 
    int Foo { get; } 
} 

public class Bar : IBar 
{ 
    int _foo; 
    public Bar(int foo) { _foo = foo; } 
    public int Foo { get { return _foo; } } 
} 

public interface IBarFactory 
{ 
    IBar CreateTest(int foo); 
} 

[Test] 
public void ExecuteTest() 
{ 
    var kernel = new StandardKernel(); 
    kernel.Bind<IBar>().To<Bar>(); 
    kernel.Bind<IBarFactory>().ToFactory(); 
    var factory = kernel.Get<IBarFactory>(); 
    var actual = factory.CreateTest(42); 
    Assert.That(actual, Is.InstanceOf<Bar>()); 
} 

Однако в моей конкретной проблеме, я хотел бы, чтобы передать заводские аргументы в зависимости от класса я конструирование, а не сам класс, как это:

public interface IBarContainer 
{ 
    IBar Bar { get; } 
} 

public class BarContainer : IBarContainer 
{ 
    IBar _bar; 
    public BarContainer(IBar bar) { _bar = bar; } 
    public IBar Bar { get { return _bar; } } 
} 

public interface ITestContainerFactory 
{ 
    IBarContainer CreateTestContainer(int foo); 
} 

[Test] 
public void ExecuteTestContainer() 
{ 
    var kernel = new StandardKernel(); 
    kernel.Bind<IBar>().To<Bar>(); 
    kernel.Bind<IBarContainer>().To<BarContainer>(); 
    kernel.Bind<ITestContainerFactory>().ToFactory(); 
    var factory = kernel.Get<ITestContainerFactory>(); 
    var actual = factory.CreateTestContainer(42); 
    Assert.That(actual.Bar, Is.InstanceOf<Bar>()); 
} 

Этот тест завершается с сообщением:

Ninject.ActivationException: Ошибка активации INT нет соответствующих переплетов доступны, и тип не является само-Привязываемое. Активация путь:
3) Инъекция междунар зависимостей в параметр обув конструктора типа Bar
2) Инъекция зависимостей IBar в параметр строку конструктора типа BarContainer
1) Заявка на IBarContainer

ли есть способ сделать фабрику выяснить, что я хочу использовать переданный аргумент «foo» при разрешении зависимости «Bar»?

ответ

3

Начиная с версии 3.2.0 из Ninject.Extensions.Factory этого поддерживается изначально, с использованием:

Ninject.Extensions.Factory.TypeMatchingArgumentInheritanceInstanceProvider 

Вы можете использовать его как это:

kernel.Bind<IxxxFactory>() 
    .ToFactory(() => new TypeMatchingArgumentInheritanceInstanceProvider()); 

Если вы посмотрите на source code, он основан на previous answer.

+0

Благодарим вас за эту информацию! Это должен быть принятый ответ, поскольку он использует встроенные функции. – McLovin

4

Hy, Поставщик экземпляра по умолчанию не использует аргументы конструктора, которые наследуются. Вы можете изменить это поведение, написав свой собственный провайдер экземпляра, как следующее:

public class CustomInstanceProvider : StandardInstanceProvider { 
    protected override ConstructorArgument[] 
     GetConstructorArguments(MethodInfo methodInfo, object[] arguments) 
     { 
      var parameters = methodInfo.GetParameters(); 
      var constructorArguments = 
       new ConstructorArgument[parameters.Length]; 
      for (int i = 0; i < parameters.Length; i++) 
      { 
       constructorArguments[i] = 
        new ConstructorArgument 
         (parameters[i].Name, arguments[i], true); 
      } 
      return constructorArguments; 
     } 
} 

Тогда вы только поручить Ninject использовать свой собственный вместо прилагаемый.

Надежда, что помогает

1

Если я понять ваш вопрос правильно, я считаю, что эта статья Ninject Wiki имеет хороший пример (Factory interface) о том, как использовать новый .ToFactory() связывание расширения, и как получить эти сгенерированные фабрики, чтобы даже создавать объекты, у которых конструкторы имеют параметры.

Смежные вопросы