c# - 每个范围的 Autofac 独特服务
问题描述
我的目标是根据范围提供接口实现。
我想用下面的代码解决这个问题,但这会导致 A 被 B 覆盖
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<ImplA>().As<IMyInterface>().InstancePerMatchingLifetimeScope(MyScope.A);
containerBuilder.RegisterType<ImplB>().As<IMyInterface>().InstancePerMatchingLifetimeScope(MyScope.B);
IContainer container = containerBuilder.Build();
using (ILifetimeScope lifetimeScope = container.BeginLifetimeScope(MyScope.A))
{
IMyInterface c = lifetimeScope.Resolve<IMyInterface>();
Console.WriteLine(c.GetType());
}
using (ILifetimeScope lifetimeScope = container.BeginLifetimeScope(MyScope.B))
{
var c = lifetimeScope.Resolve<IMyInterface>();
Console.WriteLine(c.GetType());
}
我知道我可以通过以下方式在生命周期内注册类型,但我想从一个Module
using (ILifetimeScope lifetimeScope = container.BeginLifetimeScope(MyScope.A, builder =>
{
containerBuilder.RegisterType<ImplA>().As<IMyInterface>();
}))
有没有办法在模块级别解决这个问题?
解决方案
我目前的解决方案如下
public static class AutofacExtension
{
private class ScopeModule
{
private readonly Action<ContainerBuilder> _action;
public ScopeModule(object lifetimeScopeTag, Action<ContainerBuilder> action)
{
_action = action;
}
public void ConfigurationAction(ContainerBuilder lifetimeScope)
{
_action(lifetimeScope);
}
}
public static void ForScope(this ContainerBuilder containerBuilder, object scope, Action<ContainerBuilder> action)
{
containerBuilder
.RegisterInstance(new ScopeModule(scope, action))
.Keyed<ScopeModule>(scope)
.SingleInstance();
}
public static ILifetimeScope BeginModuleLifetimeScope(this IContainer container, object scope, Action<ContainerBuilder> configurationAction = null)
{
return container.BeginLifetimeScope(scope, lifeTimeScopeContainerBuilder =>
{
var scopeModules = container.ResolveKeyed<IEnumerable<ScopeModule>>(scope);
foreach (ScopeModule scopeModule in scopeModules)
{
scopeModule.ConfigurationAction(lifeTimeScopeContainerBuilder);
}
configurationAction?.Invoke(lifeTimeScopeContainerBuilder);
});
}
}
用法
var containerBuilder = new ContainerBuilder();
containerBuilder.ForScope(MyScope.A, scope => scope.RegisterType<ImplA>().As<IMyInterface>());
containerBuilder.ForScope(MyScope.B, scope => scope.RegisterType<ImplB>().As<IMyInterface>());
IContainer container = containerBuilder.Build();
using (ILifetimeScope lifetimeScope = container.BeginModuleLifetimeScope(MyScope.A))
{
IMyInterface c = lifetimeScope.Resolve<IMyInterface>();
Console.WriteLine(c.GetType());
}
using (ILifetimeScope lifetimeScope = container.BeginModuleLifetimeScope(MyScope.B))
{
var c = lifetimeScope.Resolve<IMyInterface>();
Console.WriteLine(c.GetType());
}
推荐阅读
- google-cloud-platform - 为 gcp 监控工作区中的两个项目创建警报
- c++ - gcc 找不到 _start
- soapui - 从命令行运行时的 SOAP UI 摘要报告
- matomo - Matomo iframe 小部件报告“对于嵌入小部件,不允许使用超级用户令牌身份验证”,但身份验证令牌是只读的
- r - ggforce::geom_arc_bar 没有出现在 ggplot2 饼图上
- api - 来自 Salesforce 的 HubSpot 交易属性“PARTNER COMPANIES”在尝试获取其价值时显示为“NULL”
- docker - 将本地图像添加到 docker 卷
- android - 已安装的应用程序大小未显示在设备上
- mysql - MySQL 列设置为 varchar(255) 排序中的问题
- curl - 使用命令行连接到 Spotify API