Можно ли передать политику, используемую при разрешении, на заводской метод с использованием DryIoc?

Я пытаюсь зарегистрировать объекты в контейнере DryIoc, используя фабрику.

void Main()
{
    var container = new Container();
    container.Register<IFactory, Factory>();
    container.Register<IService>(
        made: Made.Of(r => ServiceInfo.Of<IFactory>(), f => f.Create("default")));

    container.Resolve<IService>().Dump();
    container.Resolve<IService>("name1").Dump();
    container.Resolve<IService>("name2").Dump();
}

public interface IFactory
{
    IService Create(string name);
}

public class Factory : IFactory
{
    public IService Create(string name) => new Service(name);
}

public interface IService
{
    string Name { get; }
}

public class Service : IService
{
    public Service(string name) => Name = name;
    public string Name { get; }
}

Я хочу, чтобы политика, используемая во время разрешения, была параметром, передаваемым в фабричный метод. В приведенном выше коде я жестко закодировал этот параметр "name", но я бы хотел, чтобы вместо этого использовалась политика. В частности, во 2-м и 3-м вызове Resolve параметр, передаваемый в метод фабрики, должен быть name1 а также name2 соответственно.

Три вызова для разрешения успешно выполняются только для первого вызова, два других - неудачно, поскольку в контейнере с политикой нет регистрации name1 или же name2, Теперь я знаю, что политики могут быть объектами всех типов, а не просто строками, но я бы хотел, чтобы это работало в моем случае.

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

container.Register<IService>(
    made: Made.Of(r => ServiceInfo.Of<IFactory>(), f => f.Create(<what to put here>)));
                                                                         ^
                                                                         |
...                            +-----------------------------------------+
                               |
container.Resolve<IService>("name1");

Я осмотрел пространство имен, где у меня есть Arg.Of а также ServiceInfo.Of, но, похоже, нет ничего, что указывало бы на то, что оно может быть полезным.

Обратите внимание, что правильным ответом на этот вопрос может быть даже "Это невозможно". Возможно, что нет способа сделать то, что я прошу, и что действительно должно быть несколько регистраций, по одной для каждой политики.

1 ответ

Если под "политикой" вы подразумеваете прохождение serviceKey в качестве аргумента метода фабрики, вы можете сделать это.

Вам нужен Arg.Index(int) чтобы указать пользовательский аргумент для фабричного метода:

Это может выглядеть так:

container.Register<IService>( made: Made.Of(r => ServiceInfo.Of<IFactory>(), 
    f => f.Create(Arg.Index(0)),
    r => r.ServiceKey)); 

Arg.Index(0) работает аналогично {0} заполнитель в string.Formatгде вы указываете фактические аргументы после форматирования строки. Здесь то же самое, но аргументы могут зависеть от запроса.

Извините, если он не компилируется сразу, не было доступа к ноутбуку для проверки.

Другие вопросы по тегам