对于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
答案 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/