ASP.NET Core 3依赖注入-数据访问/业务层类库

时间:2020-07-15 16:41:49

标签: asp.net asp.net-core dependency-injection

对于DI和概念来说是非常新的,所以我正在努力寻找以下解决方案:

我们有一个Web项目(MVC,Core 3)和一个类库(用于所有业务和数据层)。我们正在尝试在类库中提供一个DBContext类来处理所有数据库连接(使用连接字符串)。我们可以将IConfiguration DI到此DBContext中,以便我们可以从中提取连接字符串并将其放入本地只读字符串中。我们有一种使用此连接字符串返回SQL连接的方法。

问题是当我们在业务类中时,我们需要访问DBContext类以获得SQL连接对象。我们无法创建“新” DBContext,因为我们在其他业务类中没有IConfigration。

DBContext类库:

public class DBContext
{
    private readonly string _connectionString;
    private readonly IConfiguration _configuration;

    public DBContext(IConfiguration configuration)
    {
        _configuration = configuration;
        _connectionString = configuration.GetConnectionString("db");
    }

    public SqlConnection Connection()
    {
        return new System.Data.SqlClient.SqlConnection(_connectionString);
    }
}

因此,问题出在我们查看类库中的Customer类时:

客户类别:

public class Customer
{

    public int CustomerId { get; set; }
    public string CustomerName { get; set; }


    public Customer(int customerId)
    {
        //load customer from the db from the id

        using (IDbConnection db = new DBContext().Connection())
        {
            //call SQL Stored Procedure here ....
        }

    }

}

我们无法创建“新的” DBContext来访问连接,因为在“客户类”中,我们没有IConfiguration对象可传递给构造函数。

我们如何以“正确”的方式实现这一目标?

就像必须将IConfiguration对象DI到每个单个类库构造函数中一样糟糕。来自所有Web控制器的客户,因此我们可以将其传递给DBContext吗?似乎已经long绕了。

很抱歉,如果这是非常基础的DI内容,但正在努力寻找一个很好的示例来说明如何做这些东西。

预先感谢

Ro

1 个答案:

答案 0 :(得分:0)

public class Customer
{
    private readonly ApplicationDbContext _context;
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }


    public Customer(ApplicationDbContext context, int customerId)
    {
        _context = context; //use _context to reference the db context.
        //do stuff
    }

}

然后在Startup.cs-> ConfigureServices()方法中:

services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DevDb")));

为Dapper编辑:

在appsettings.json中:

"ConnectionStrings": {  
    "DefaultConnection": "<connection string here>"  
  }  

然后在解决方案中添加一个名为ConnectionString的类。我们将使用此类来保存配置文件中的连接字符串值,并通过依赖注入将其用于我们的类中。

public sealed class ConnectionString  
{  
    public ConnectionString(string value) => Value = value;  
  
    public string Value { get; }  
}  

然后在Startup.cs中的ASP.NET Core依赖项注入容器中注册配置

var connectionString = new ConnectionString(Configuration.GetConnectionString("DefaultConnection"));  
services.AddSingleton(connectionString); 

然后添加您的存储库类:

using Dapper;  
  
public class MovieRepository
{  
    private readonly ConnectionString _connectionString;  
  
    public MovieRepository(ConnectionString connectionString)  
    {  
        _connectionString = connectionString;  
    }  
  
    public async Task<IEnumerable<MovieModel>> GetAllMovies()  
    {  
        const string query = @"SELECT m.Id, m.Name,d.Name AS DirectorName, m.ReleaseYear  
                                FROM Movies m  
                                INNER JOIN Directors d  
                                ON m.DirectorId = d.Id";  
  
        using (var conn = new SqlConnection(_connectionString.Value))  
        {  
            var result = await conn.QueryAsync<MovieModel>(query);  
            return result;  
        }  
    }  
}  

然后在您的DI容器中注册Repository类。将以下代码添加到ConfigureServices方法。

services.AddScoped<MovieRepository>();  

添加控制器类MoviesController.cs并编写一个操作方法以使用此MovieRepository提取所有电影。

[ApiController]  
public class MoviesController : ControllerBase  
{  
    private readonly MovieRepository _movieRepository;  
  
    public MoviesController(MovieRepository movieRepository)  
    {  
        _movieRepository = movieRepository;  
    }  
  
    [HttpGet("api/movies")]  
    public async Task<IActionResult> GetMovies()  
    {  
        return Ok(await _movieRepository.GetAllMovies());  
    }  
}  

在此示例中,您的ApplicationDbContext等效于影片存储库。答案来自:https://www.c-sharpcorner.com/article/using-dapper-for-data-access-in-asp-net-core-applications/

相关问题