Учитывая ваше описание использования, я бы сказал, что у вас есть несколько вариантов.
Во-первых, вы можете просто зарегистрировать свой собственный набор зависимостей, включая продолжительность жизни. Наличие одного или двух «дублирующих» фрагментов кода в этом отношении не является чем-то большим, учитывая различия между приложением и тот факт, что регистрации выглядят довольно маленькими.
Во-вторых, вы можете обернуть общую часть (минус область видимости) в метод расширения ContainerBuilder, который может использоваться в каждом приложении. Это все равно означает, что каждое приложение имеет небольшой «дублирующий код», но общая логика будет завернута в простое расширение.
public static IRegistrationBuilder<TLimit, ScanningActivatorData, DynamicRegistrationStyle>
RegisterConnection<TLimit, ScanningActivatorData, DynamicRegistrationStyle>(this ContainerBuilder builder)
{
// Put the common logic here:
builder.Register(...).AsImplementedInterfaces();
}
Потребляя такое расширение в каждом приложении будет выглядеть следующим образом:
builder.RegisterConnection().InstancePerHttpRequest();
// or
builder.RegisterConnection().InstancePerLifetimeScope();
Наконец, если вы знаете, что это либо веб или не веб, вы могли бы сделать пользовательский модуль, который обрабатывает переключатель :
public class ConnectionModule : Autofac.Module
{
bool _isWeb;
public ConnectionModule(bool isWeb)
{
this._isWeb = isWeb;
}
protected override void Load(ContainerBuilder builder)
{
var reg = builder.Register(...).AsImplementedInterfaces();
if(this._isWeb)
{
reg.InstancePerHttpRequest();
}
else
{
reg.InstancePerLifetimeScope();
}
}
}
В каждом приложении, вы можете затем зарегистрировать модуль:
// Web application:
builder.RegisterModule(new ConnectionModule(true));
// Non-web application:
builder.RegisterModule(new ConnectionModule(false));
В качестве альтернативы вы упомянули, что ваша продолжительность жизни в других приложениях имеет имя.Вы можете сделать свой модуль взять имя:
public class ConnectionModule : Autofac.Module
{
object _scopeTag;
public ConnectionModule(object scopeTag)
{
this._scopeTag = scopeTag;
}
protected override void Load(ContainerBuilder builder)
{
var reg = builder.Register(...)
.AsImplementedInterfaces()
.InstancePerMatchingLifetimeScope(this._scopeTag);
}
}
Потребление схожа:
// Web application (using the standard tag normally provided):
builder.RegisterModule(new ConnectionModule("httpRequest"));
// Non-web application (using your custom scope name):
builder.RegisterModule(new ConnectionModule("yourOtherScopeName"));
Я бы не рекомендовал просто использовать InstancePerLifetimeScope
в веб-приложении, если это не на самом деле то, что вы собираетесь. Как указано в других ответах/комментариях, InstancePerHttpRequest
использует конкретную область видимости по времени, чтобы было безопасно создавать дочерние области жизни; использование InstancePerLifetimeScope
не имеет такого ограничения, поэтому вы фактически получите одно соединение на одну дочернюю область, а не одно соединение для запроса. Я лично не предполагаю, что другие разработчики не будут использовать охват жизненного цикла ребенка (which is a recommended practice), поэтому в моих приложениях я очень специфичен. Если вы полностью контролируете свое приложение, и вы можете гарантировать, что вы не создаете дополнительные дочерние области или вам действительно нужно одно соединение для каждой области, то, возможно, InstancePerLifetimeScope
решит вашу проблему.
У вас есть конкретные времена жизни в виду для соединений? Если да, являются ли они разными сроками жизни для каждого приложения или они всегда одинаковы независимо от типа приложения? Как насчет пула? Собираетесь ли вы в некоторых приложениях, а не в других? –
Как будто вы сказали: «Расширения MVC используют именованный объем, чтобы достичь механизма один раз за запрос». Http с именем scope не существует, когда вы используете модуль в консольном приложении. В настоящее время я смотрю, какая единица работы будет и которая будет инкапсулирована в область. –