ormlite-servicestack,C#,Dapper,Simple Injector,ormlite Servicestack" /> ormlite-servicestack,C#,Dapper,Simple Injector,ormlite Servicestack" />

C# SimpleI注入器-注册多个数据库连接

C# SimpleI注入器-注册多个数据库连接,c#,dapper,simple-injector,ormlite-servicestack,C#,Dapper,Simple Injector,ormlite Servicestack,我正在使用一个现有的Web Api,它使用简单的注入器来注册单个数据库连接。我需要创建一个端点以从不同的数据库获取信息,但我不知道如何注册新连接 以下是主数据库的现有注册: _container.Register<IDataBaseSqlServerDapper>( () => new DataBaseSqlServerDapper(SqlServerDb.ConnectionString(), LogManager.GetLogger(""

我正在使用一个现有的Web Api,它使用简单的注入器来注册单个数据库连接。我需要创建一个端点以从不同的数据库获取信息,但我不知道如何注册新连接

以下是主数据库的现有注册:

_container.Register<IDataBaseSqlServerDapper>(
    () => new DataBaseSqlServerDapper(SqlServerDb.ConnectionString(),
    LogManager.GetLogger("")));

_container.RegisterWebApiRequest<IDbConnectionFactory>(
    () => new OrmLiteConnectionFactory(SqlServerDb.ConnectionString(),
    new SqlServerOrmLiteDialectProvider()));

_container.RegisterWebApiRequest(
    () => new PetaPoco.Database(Connection.SurveyEngine) {
        IsolationLevel = IsolationLevel.Snapshot
    });
\u container.Register(
()=>新数据库SQLServerDapper(SqlServerDb.ConnectionString(),
LogManager.GetLogger(“”);
_container.RegisterWebApiRequest(
()=>新的OrmLiteConnectionFactory(SqlServerDb.ConnectionString(),
新的SqlServerOrmLiteDialectProvider());
_container.RegisterWebApiRequest(
()=>新的PetaPoco.Database(Connection.SurveyEngine){
IsolationLevel=IsolationLevel.Snapshot
});
因此,我阅读了RegisterCollection方法,并尝试了以下方法:

_container.RegisterCollection<IDataBaseSqlServerDapper>(new[]
{
   new DataBaseSqlServerDapper(SqlServerDb.ConnectionString(), LogManager.GetLogger("")),
   new DataBaseSqlServerDapper(AdmbbDb.ConnectionString(), LogManager.GetLogger(""))
});

_container.RegisterCollection<IDbConnectionFactory>(new[]
{
    new OrmLiteConnectionFactory(
        SqlServerDb.ConnectionString(), 
        new SqlServerOrmLiteDialectProvider()),
    new OrmLiteConnectionFactory(
        AdmbbDb.ConnectionString(), 
        new SqlServerOrmLiteDialectProvider())
});

_container.RegisterCollection<PetaPoco.Database>(new[]
{
     new PetaPoco.Database(Connection.SurveyEngine) { 
        IsolationLevel = IsolationLevel.Snapshot },
     new PetaPoco.Database(Connection.Admbb) { 
        IsolationLevel = IsolationLevel.Snapshot }
});
\u container.RegisterCollection(新[]
{
新数据库SQLServerDapper(SqlServerDb.ConnectionString(),LogManager.GetLogger(“”),
新数据库SQLServerDapper(AdmbbDb.ConnectionString(),LogManager.GetLogger(“”)
});
_container.RegisterCollection(新[]
{
新奥姆利特连接工厂(
SqlServerDb.ConnectionString(),
新的SqlServerOrmLiteDialectProvider()),
新奥姆利特连接工厂(
AdmbbDb.ConnectionString(),
新的SqlServerOrmLiteDialectProvider())
});
_container.RegisterCollection(新[]
{
新的PetaPoco.Database(Connection.SurveyEngine){
IsolationLevel=IsolationLevel.Snapshot},
新的PetaPoco.Database(Connection.Admbb){
IsolationLevel=IsolationLevel.Snapshot}
});
SqlServerDb、AdmbbDd和Connection是包含连接字符串名称的类

但我得到了一个错误:

配置无效。为IDapperQueryFactory类型创建实例失败。DapperQueryFactory类型的构造函数包含名为“dataBaseSqlServerDapper”且未注册的IDataBaseSqlServerDapper类型的参数。请确保已注册IDataBaseSqlServerDapper,或更改DapperQueryFactory的构造函数。然而,有一个IEnumerable的注册;你是想依靠我吗


如何解决此问题?

在现有情况下,您指定类型
IDataBaseSqlServerDapper
可用于注入,这反过来会正确注入到对象中(在本例中,是一个实现
IDapperQueryFactory
的类)

在第二种情况下,您正在注册多个类型为
IDataBaseSqlServerDapper
的服务。这意味着您的DI不知道如何解析单个
IDataBaseSqlServerDapper
,而只解析它们的集合

这意味着您必须更改构造函数以接受
IEnumerable
或注册非集合
IDataBaseSqlServerDapper

Simple Injector的文档列出了一个很好的示例,说明如何同时使用
寄存器
集合。寄存器
使其工作()


至于你的问题,你说:

我需要创建一个端点以从不同的数据库获取信息,但我不知道如何注册新连接

如果您只是想更改数据的去向,那么您就不能替换现有的旧处理程序吗

如果您的目标是从多个数据源加载数据,那么您需要有某种逻辑,允许您的代码确定应该使用哪个源来存储/加载数据


simple injector文档中的示例为类似的内容提供了良好的基础,它不需要您重写使用injected
IDataBaseSqlServerDapper
的类。我的情况与此类似,但稍微简单一点。我发布了我的解决方案,任何人登陆这里都会遇到像我这样的问题

问题 我需要一种方法来使用单个具体类型的多个实例(在我的例子中是
NPoco.Database
),并使用不同的参数(连接字符串名称)初始化。由于使用的类实现了
ILogger
,并且都具有无参数构造函数,因此我发现很难弄清楚如何使我的场景工作

解决方案 最后,我为我需要连接的每个数据库创建了一个简单的
NPoco.Database
子类,然后使用
Container.RegisterConditional
注册实例。由于
RegisterConditional
没有采用构造函数的重载,因此我必须为这些子类中的每一个子类提供无参数构造函数,这些构造函数使用正确的连接字符串名称调用基本
数据库
类。最后,一些使用者来自外部NuGet包(在我的组织内部),依赖于注入的
IDatabase
,而不是派生类型,因此我不能仅仅依靠注册派生类型并让SimpleInjector根据这一点来解决问题

代码 综上所述,以下是我的解决方案

NPoco.数据库的子类
公共类第一个子数据库:数据库
{
公共子数据库()
:base(“第一次子连接”){}
}
公共类第二个子数据库:数据库
{
公共子数据库()
:base(“SecondSubConnection”){}
}
登记处
container.register条件(
生活方式。范围,
c=>c.Consumer.ImplementationType.FullName?.StartWith(
“external.lib.”,StringComparison.OrdinalIgnoreCase)??false);
容器注册表条件(
生活方式。范围,
c=>c.Consumer.ImplementationType==typeof(LocalConsumerClass));

注意:“external.lib.”只是外部NuGet包中所有内容的名称空间。这使未来的编辑(包括我自己)不必花时间去弄清楚为什么要实例化该包中的另一个服务的依赖关系。

我没有改变数据的去向,我需要从另一个d获取信息