Я использую Autofac, и у меня есть несколько классов, которые запрашивают параметр типа string и name lang. Есть ли способ зарегистрировать строковое значение для всех параметров с именем "lang", чтобы оно разрешалось автоматически? Я не хочу редактировать какие-либо конструкторы, так как это не мой код (я знаю, что принятие, например, CultureInfo облегчит регистрацию..)
Что-то приводит к короткому синтаксису вроде builder.Register(lang => "en-US").As().Named("lang")
было бы идеально.
Спасибо.
Ответ 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"));
вы можете разрешить свой класс и передать параметры в конструкторе.