【发布时间】:2021-11-12 08:22:14
【问题描述】:
我一直在学习本教程,以便从我的类库中的 MVC 项目访问我的 appsettings.json。 geek-tutorial
我的类库中有一个这样的类
using dapper;
public class SqlDataAccess : IConfigManager
{
private readonly IConfiguration _configuration;
public SqlDataAccess(IConfiguration configuration)
{
this._configuration = configuration;
}
public List<T> LoadData<T>(string sql)
{
using (IDbConnection cnn = new SqlConnection(GetConnectionString()))
{
return cnn.Query<T>(sql).ToList();
}
}
public int SaveData<T>(string sql, T data)
{
using (IDbConnection cnn = new SqlConnection(GetConnectionString()))
{
return cnn.Execute(sql, data);
}
}
public string GetConnectionString(string connectionName = "URLShortnerDB")
{
return this._configuration.GetConnectionString(connectionName);
}
}
界面:
public interface IConfigManager
{
string GetConnectionString(string connectionName);
}
我在我的 mvc startup.cs 中添加了services.AddSingleton<IConfigManager, SqlDataAccess>();
但是现在我想使用我的 SqlDataAccess 类并调用另一个类的方法,例如:
public static class ShortUrlProcessor
{
public static ShortURLModel GetOriginalURL(string shortUrl)
{
string sql = $@"SELECT * FROM dbo.shorturl WHERE shortUrl = '{ shortUrl }'";
var originalURLEnum = SqlDataAccess.LoadData<ShortURLModel>(sql); //<--- problem
return originalURLEnum.First();
}
}
但是SqlDataAccess 没有被实例化,为了实现var _sqldataaccess = SqlDataAccess(),我需要传入一个在类的构造函数中定义的参数。我不知道要传递什么?我在这个 ShortUrlProcessor 类中没有任何 IconfigurationManager。我知道这样做的原因是依赖注入,但是我仍然不明白这一切是如何工作的?
【问题讨论】:
-
使 ShortUrlProcessor 成为非静态的,然后执行您遵循的相同构造函数注入器模式,以便 SqlDataAccess 类接收 IConfiguration 实例。您可能需要在您的 IoC 容器中注册 ShortUrlProcessor。您似乎对依赖注入概念不熟悉 - 我强烈推荐 Deep Dive Into Dependency Injection And Writing Quality Decoupled Code by Miguel Castro。这是帮助理解这些概念的非常有用的资源。
-
一个很好的通用指导是避免使用静态类并避免通过“new”关键字直接调用对象的构造函数(可能是愚蠢的 DTO 对象除外)。这有助于保持您的方法为依赖注入正确结构化,并最终使它们可进行单元测试。
-
您的代码可能容易受到 SQL 注入攻击。 (几乎)永远不要使用字符串连接来形成 SQL 查询。这是一个向量,使不受信任的输入成为 SQL 语句的一部分。相反,您应该使用参数化查询。 This page 解释了如何使用 ADO.NET、Entity Framework 或 Dapper 安全地执行 SQL。
-
@mason 感谢您的评论,我已经从 ShortUrlProcessor 中的所有内容中删除了静态,但是我没有完全理解这有什么帮助,我确实对依赖注入和 ASP.NET 非常陌生.您的第一条评论是否有可能被分解为进一步的步骤?谢谢。编辑:感谢深潜视频提示
-
如果你的类是静态的,那么你不能使用静态构造函数进行正常的依赖注入(通过构造函数注入),因此它不能轻易地使用由 DI 容器创建的对象。并且是静态的会迫使其他类直接引用它,这违反了SOLID 中的依赖倒置原则。其他需要 GetOriginalUrl 的类应该是针对抽象(接口)而不是具体实现(类)的代码。您使用 SqlDataAccess 和 IConfiguration 正确地做到了。
标签: c# asp.net-mvc asp.net-core dependency-injection asp.net-core-mvc