Получите расширение фабрики ninject, чтобы позволить фабричным параметрам передаваться в зависимости

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

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 : Error activating int No matching bindings are available, and the type is not self-bindable. Activation path:
3) Injection of dependency int into parameter foo of constructor of type Bar
2) Injection of dependency IBar into parameter bar of constructor of type BarContainer
1) Request for IBarContainer

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

Ответы на вопрос(3)

Решение Вопроса

значально, используя:

Ninject.Extensions.Factory.TypeMatchingArgumentInheritanceInstanceProvider

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

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

Если вы посмотрите наисходный кодон основан напредыдущий ответ.

 10 сент. 2015 г., 12:29
Спасибо за эту информацию! Это должен быть принятый ответ, поскольку он использует встроенную функциональность.

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

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 Wiki есть хороший пример (Заводской интерфейс ) о том, как использовать новое расширение привязки .ToFactory () и как заставить эти сгенерированные фабрики даже создавать объекты, конструкторы которых имеют параметры.

Ваш ответ на вопрос