.net 如何注入多个QueryFactory?

new9mtju  于 2023-03-13  发布在  .NET
关注(0)|答案(1)|浏览(103)

SqlKata文档列出了以下代码:

  • .NET 6*
builder.Services.AddTransient<QueryFactory>((e) =>
{
    var connection = new SqlConnection(CONST.KenticoConnectionString);
    var compiler = new SqlServerCompiler();

    return new QueryFactory(connection, compiler);
});
  • 家庭控制器.cs*
using SqlKata;
using SqlKata.Execution;

public class HomeController {

    private readonly QueryFactory db;

    public HomeController(QueryFactory db) {

        this.db = db;

    }

    public IActionResult Index() {

        // Here books is of type `IEnumerable<dynamic>`
        var books = db.Query("Books").Where("IsPublished", true).Get();

        // or `IEnumerable<Book>` if using the Generic overload
        var books = db.Query("Books").Where("IsPublished", true).Get<Book>();

        return Ok(books);

    }

}

我将如何使用多个QueryFactory?我有两个不同的数据库,我需要查询它们具有单独的连接字符串。
我可以在Program / Startup中设置多个QueryFactor,但我不知道如何注入正确的QueryFactor。

llmtgqce

llmtgqce1#

您可以为QueryFactory创建一个工厂,该工厂将动态返回一个示例,其中包含动态注入的ConnectionString

public class QueryFactoryFactory : IQueryFactoryFactory
{
    public QueryFactory CreateQueryFactory(string connectionString)
    {
        var connection = new SqlConnection(connectionString);

        return new QueryFactory(connection, new SqlServerCompiler());
    }
}

public interface IQueryFactoryFactory
{
    QueryFactory CreateQueryFactory(string connectionString);
}

它应该在您的ServiceCollection中注册:

builder.Services.AddScoped<IQueryFactoryFactory, QueryFactoryFactory>();

之后,您可以将工厂注入到控制器中,并基于连接字符串获取所需的QueryFactory,前提是您可以从IConfiguration获取连接字符串(或以任何其他方式):

public class HomeController
{
    private readonly IConfiguration _configuration;
    private readonly IQueryFactoryFactory _factory;

    public HomeController(IConfiguration configuration, IQueryFactoryFactory factory)
    {
        _factory = factory;
        _configuration = configuration;
    }

    public IActionResult Index()
    {
        // use the needed connectionString name instead of 'first'
        var books = _factory.CreateQueryFactory(_configuration.GetConnectionString("first"))
            .Query("Books")
            .Where("IsPublished", true)
            .Get();

        return Ok(books);
    }
}

也可以为每个连接字符串创建单独的派生类,并在IoC中注册它们,但是,这是一种糟糕的方法,为了避免这种情况,还发明了工厂模式:

public class ConcreteQueryFactory1 : QueryFactory
{
    public ConcreteQueryFactory1()
        : base(new SqlConnection("connectionString1"), new SqlServerCompiler())
    {

    }
}

public class ConcreteQueryFactory2 : QueryFactory
{
    public CustomQueryFactory2(IDbConnection connection, Compiler compiler, int timeout = 30)
        : base(connection, compiler, timeout)
    {

    }
}

与第二种方法相比,工厂的主要好处是:
1.你可以改变创建对象的方式,而不影响你代码的其余部分--灵活性;
1.工厂为对象的创建提供了一个单一的点--封装;
1.通过使用工厂,您可以将对象创建的关注点与对象使用的关注点分离--责任分离;
1.您可以轻松地创建用于测试目的的模拟对象-可测试性

相关问题