Возможно ли иметь какой-то динамический KeyFilter в автофаке? - PullRequest
0 голосов
/ 26 октября 2019

KeyFilter, используемый в Autofac, полезен, но на самом деле я думаю, что он не динамический, потому что ключ здесь предустановлен / настроен / определен и привязан к параметрам конструктора во время компиляции. Нет способа заставить что-то подобное работать во время выполнения.

Вот сценарий, когда во время разрешения для некоторого экземпляра может быть определен ключ (который может динамически изменяться в зависимости от текущего контекста). Этот ключ следует учитывать перед разрешением для экземпляра. Я думаю, что функция Multitenant, поддерживаемая autofac, очень близка к этому требованию. Однако я не думаю, что он может быть легко использован и поддерживает внедрение конструктора (нам, возможно, придется всегда создавать область действия и разрешать экземпляры явно и вручную, что очень похоже на способ поиска службы).

Примененоэта мнимая особенность в примере выбора версии кода, давайте посмотрим, насколько она может быть полезна. Предположим, у меня есть 2 реализации для одного и того же интерфейса, каждая соответствует одной версии кода (v1 и v2). Теперь конструктор, использующий этот интерфейс, не заботится о том, какая версия, но контекст предоставит контейнеру IoC какую версию, чтобы он мог определить правильную реализацию, соответствующую этой версии.

public interface ISender {
    void Send(string msg);
}
//version v1 
public class SlowSender : ISender {
    //...
}
//version v2
public class FastSender : ISender {
    //...
}

Теперь потребительclass:

public class MyConsumer {
    readonly ISender _sender;
    public MyConsumer(ISender sender){
        _sender = sender;
    }
    //do whatever with what ISender provides
}

Так что здесь, при разрешении для MyConsumer, autofac должен знать, какую версию выбрать для меня, например, через некоторый поставщик контекстной информации, такой как:

public class ContextInfoProvider : IContextInfoProvider //just an example
{
    public string GetCurrentVersion(){
        //can return some value picked from HttpContext.Current.Request
        //or any ambient variable that can be injected at some very early time.
    }
}

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

Я знаю, что это возможно, но можетеще не были реализованы autofac. Это действительно жаль. Есть ли у вас альтернативное решение с текущими функциями, поддерживаемыми autofac? Обратите внимание, что я не хочу использовать подобный сервису-локатору код, иногда нам приходится использовать его таким образом, но почти в то время, когда нам нужен способ внедрения-зависимости-зависимости, он просто аккуратный и чистый.

1 Ответ

1 голос
/ 26 октября 2019

Вы можете зарегистрировать лямбду. Поместите заводскую логику в эту лямбду.

builder.Register(ctx =>
  var version = ctx.Resolve<IContextInfoProvider>().GetVersion();
  if(version == 1)
  {
    return new SlowSender();
  }
  return new FastSender();
).As<ISender>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...