Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Зарегистрируйте строковое значение для конкретного имени параметра

Автор вопроса: Tomas GrosupОтветов: 2

Я использую Autofac, и у меня есть несколько классов, которые запрашивают параметр типа string и name lang. Есть ли способ зарегистрировать строковое значение для всех параметров с именем "lang", чтобы оно разрешалось автоматически? Я не хочу редактировать какие-либо конструкторы, так как это не мой код (я знаю, что принятие, например, CultureInfo облегчит регистрацию..)

Что-то приводит к короткому синтаксису вроде builder.Register(lang => "en-US").As().Named("lang")

было бы идеально.

Спасибо.

autofacinversion-of-controlioc-container

Ответы

Ответ 1 · рейтинг 10 · Travis Illig

Довольно простой способ решить эту проблему - использовать специальный модуль Autofac.

Во-первых, реализуйте модуль и обработайте событие IComponentRegistration.Preparing. Здесь вы также будете хранить значение для вашего параметра:

using System;
using Autofac;
using Autofac.Core;

public class LangModule : Module:
{
  private string _lang;
  public LangModule(string lang)
  {
    this._lang = lang;
  }

  protected override void AttachToComponentRegistration(
    IComponentRegistry componentRegistry,
    IComponentRegistration registration)
  {
    // Any time a component is resolved, it goes through Preparing
    registration.Preparing += InjectLangParameter;
  }

  protected void InjectLangParameter(object sender, PreparingEventArgs e)
  {
    // Add your named parameter to the list of available parameters.
    e.Parameters = e.Parameters.Union(
      new[] { new NamedParameter("lang", this._lang) });
  }
}

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

var builder = new ContainerBuilder();
builder.RegisterModule(new LangModule("my-language"));
builder.RegisterType<LangConsumer>();
...
var container = builder.Build();

Теперь, когда вы разрешаете любой тип со строковым параметром "lang", ваш модуль будет вставлять предоставленное вами значение.

Если вам нужно быть более конкретным, вы можете использовать PreparingEventArgs в обработчике событий, чтобы определить, например, какой тип разрешается (e.Component.Activator.LimitType) и т. д. Затем вы можете решить на лету, следует ли включать ваш параметр.

Ответ 2 · Anton Sizikov

Взгляните на этот пример:

builder.Register<ClassName>((c, p) =>
{
var p2 = p.Named<string>("lang");
return new ClassName(p2);
});
var container = builder.Build();
var m = container.Resolve<ClassName>(new NamedParameter("lang", "en-US"));
var m2 = container.Resolve<ClassName>(new NamedParameter("lang", "fr-FR"));

вы можете разрешить свой класс и передать параметры в конструкторе.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы