4

我有一个 .net 核心库,需要将DbProviderFactory其作为依赖项传递给服务。在可预见的未来它应该是 SQL Server,所以我想我可以做这样的事情:

services.AddSingleton<IMyService>(di=>new MyService(SqlClientFactory.Instance));

...但是我的 appsettings.json 文件中有多个 db 连接字符串,并且我没有看到一种机制来告诉使用Instance哪个连接。

如何配置DbProviderFactory以使用正确的连接和连接字符串?appsettings 文件中没有连接或提供程序的“名称”概念。

4

1 回答 1

1

配置中的连接字符串设置有一个provider 属性。如果在本地配置了正确的提供程序,您可以按如下方式使用它:

[System.Configuration.ConfigurationProperty("providerName", DefaultValue=Mono.Cecil.CustomAttributeArgument)] 公共字符串 ProviderName { get; 放; }

<connectionStrings>
    <add name="Example" 
         providerName="System.Data.SqlClient" 
         connectionString="Data Source=1.1.1.1;Integrated Security=True"/>
</connectionStrings>

可以这样调用:

DbProviderFactories.GetFactory(settings.ProviderName);

通常,如果您只有一个 DBConnection,您可以创建一个辅助方法来检索 ProviderFactory:

public static DbProviderFactory GetProviderFactory(DbConnection connection)
{
    DbProviderFactory providerFactory = null;
    Type connectionType = connection.GetType();
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

    // Check for DbConnection.DbProviderFactory
    PropertyInfo providerFactoryInfo = connectionType.GetProperty("DbProviderFactory", flags);
    if (providerFactoryInfo != null)
        providerFactory = (DbProviderFactory)providerFactoryInfo.GetValue(connection, null);

    // Check for DbConnection.ConnectionFactory.ProviderFactory
    if (providerFactory == null)
    {
        PropertyInfo connectionFactoryInfo = connectionType.GetProperty("ConnectionFactory", flags);
        object connectionFactory = connectionFactoryInfo.GetValue(connection, null);
        providerFactoryInfo = connectionFactory.GetType().GetProperty("ProviderFactory", flags);
        providerFactory = (DbProviderFactory)providerFactoryInfo.GetValue(connectionFactory, null);
    }

    // No match
    if (providerFactory == null)
        throw new InvalidOperationException("ProviderFactory not found for connection");

    return providerFactory;
}

但是 .NET 核心不包括反射,所以这不能开箱即用。

于 2018-08-23T14:42:37.393 回答