Поставщик пользовательских экземпляров Ninject Factory

Я использую расширение фабрики Ninject и создаю собственный поставщик экземпляров, описанный в вики:

class UseFirstArgumentAsNameInstanceProvider : StandardInstanceProvider
{
    protected override string GetName(System.Reflection.MethodInfo methodInfo, object[] arguments)
    {
        return (string)arguments[0];
    }

    protected override Parameters.ConstructorArgument[] GetConstructorArguments(System.Reflection.MethodInfo methodInfo, object[] arguments)
    {
        return base.GetConstructorArguments(methodInfo, arguments).Skip(1).ToArray();
    }
}

Я определил следующий интерфейс фабрики:

interface IFooFactory
{
    IFoo NewFoo(string template);
}

Я создал следующие привязки:

kernel.Bind<IFooFactory>().ToFactory(() => new UseFirstArgumentAsNameInstanceProvider());
kernel.Bind<IFoo>().To<FooBar>().Named("Foo");

Теперь, когда я позвоню следующее, я получу экземпляр FooBar:

var foobar = fooFactory.NewFoo("Foo");

Это все прекрасно работает. Однако я хотел бы что-то вроде этого:

interface IFooTemplateRepository
{
     Template GetTemplate(string template);
}

У меня есть хранилище, которое возвращает шаблон на основе имени ("Foo"), и я хочу передать шаблон в качестве аргумента конструктора.

public class FooBar
{
    public FooBar(Template template)
    {
    }
}

Это возможно? Я не уверен, что должно иметь зависимость от ITemplateRepository.

1 ответ

Решение

Не используйте контейнер IoC для создания экземпляров сущностей. Это бизнес-логика и, следовательно, она не принадлежит корню композиции. Правильный способ справиться с этим - использовать ORM напрямую (например, с шаблоном репозитория, который вы используете).

var template = this.templateRepository.Get("SomeTemplate");
var fooBar = this.fooBarFactory.CreateFooBar(template);
Другие вопросы по тегам