Autofac 按名称解析依赖服务
Autofac resolve dependant services by name
是否可以注册具有可根据设置更改的依赖项的单个服务?
例如
A DBExecutor
需要一个不同的 DBconnection
对象,具体取决于它 运行 所在的地理区域。
我试过
builder.RegisterType<DbConnection>().Named<IDbConnection>("US")
builder.RegisterType<DbConnection>().Named<IDbConnection>("AU")
builder.RegisterType<SqlExecutor>().As<IDbExecutor>();
我想用
之类的方式解决服务问题
var au = container.ResolveNamed<IDbExecutor>("AU");
var us = container.ResolveNamed<IDbExecutor>("US");
但是这不起作用,因为 IDbExecutor
本身还没有用密钥注册,如果我尝试正常的 Resolve,它不会起作用,因为它无法创建依赖服务。
基本上我只想要一个 IDbExecutor
的实例,它具有基于特定参数的 DBConnection
。
我试图在更一般的意义上这样做,所以我尽量避免使用任何特定代码。
我目前拥有的不使用键控服务的通用代码看起来像
var job = (IJob) lifetimeScope.Resolve(bundle.JobDetail.JobType);
其中 JobType
是 class Type
并且取决于这是否可能最终版本看起来像
var job = (IJob) lifetimeScope.Resolve(bundle.JobDetail.JobType, bundle.JobDetail.JobDataMap["Region"]);
其中 bundle.JobDetail.JobDataMap["Region"]
将 return "AU"
或 "US"
您将无法操纵它来解析已命名的 IDbExecutor
,因为您没有将其注册为已命名的。这也可能不是最好的主意,因为它暗示 IDbExecutor
以某种方式 "knows" 关于它的依赖关系,这是不应该的 - 实现 知道,但是 interface/service 没有 - 也不应该。
您可以通过将 SqlExecutor
更新为使用 the IIndex<X,B>
relationship in Autofac 来获得接近您想要的东西。不要只在构造函数中使用 IDbConnection
,而是使用 IIndex<string,IDbConnection>
.
当您需要获取连接时,使用作业类型从索引字典中查找:
public class SqlExecutor
{
private IIndex<string, IDbConnection> _connections;
public SqlExecutor(IIndex<string, IDbConnection> connections)
{
this._connections = connections;
}
public void DoWork(string jobType)
{
var connection = this._connections[jobType];
// do something with the connection
}
}
另一种方法是 create a delegate factory for the SqlExecutor
that takes in the job type and automatically picks the right named service. That's a bit more involved so check out the documentation for an example。
是否可以注册具有可根据设置更改的依赖项的单个服务?
例如
A DBExecutor
需要一个不同的 DBconnection
对象,具体取决于它 运行 所在的地理区域。
我试过
builder.RegisterType<DbConnection>().Named<IDbConnection>("US")
builder.RegisterType<DbConnection>().Named<IDbConnection>("AU")
builder.RegisterType<SqlExecutor>().As<IDbExecutor>();
我想用
之类的方式解决服务问题var au = container.ResolveNamed<IDbExecutor>("AU");
var us = container.ResolveNamed<IDbExecutor>("US");
但是这不起作用,因为 IDbExecutor
本身还没有用密钥注册,如果我尝试正常的 Resolve,它不会起作用,因为它无法创建依赖服务。
基本上我只想要一个 IDbExecutor
的实例,它具有基于特定参数的 DBConnection
。
我试图在更一般的意义上这样做,所以我尽量避免使用任何特定代码。
我目前拥有的不使用键控服务的通用代码看起来像
var job = (IJob) lifetimeScope.Resolve(bundle.JobDetail.JobType);
其中 JobType
是 class Type
并且取决于这是否可能最终版本看起来像
var job = (IJob) lifetimeScope.Resolve(bundle.JobDetail.JobType, bundle.JobDetail.JobDataMap["Region"]);
其中 bundle.JobDetail.JobDataMap["Region"]
将 return "AU"
或 "US"
您将无法操纵它来解析已命名的 IDbExecutor
,因为您没有将其注册为已命名的。这也可能不是最好的主意,因为它暗示 IDbExecutor
以某种方式 "knows" 关于它的依赖关系,这是不应该的 - 实现 知道,但是 interface/service 没有 - 也不应该。
您可以通过将 SqlExecutor
更新为使用 the IIndex<X,B>
relationship in Autofac 来获得接近您想要的东西。不要只在构造函数中使用 IDbConnection
,而是使用 IIndex<string,IDbConnection>
.
当您需要获取连接时,使用作业类型从索引字典中查找:
public class SqlExecutor
{
private IIndex<string, IDbConnection> _connections;
public SqlExecutor(IIndex<string, IDbConnection> connections)
{
this._connections = connections;
}
public void DoWork(string jobType)
{
var connection = this._connections[jobType];
// do something with the connection
}
}
另一种方法是 create a delegate factory for the SqlExecutor
that takes in the job type and automatically picks the right named service. That's a bit more involved so check out the documentation for an example。