无法访问应用设置.Json从类库



为了访问我的应用程序,我一直在遵循本教程。json从我的MVC项目在我的类库。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);
}

我已经添加了services.AddSingleton<IConfigManager, SqlDataAccess>();在我的mvc启动。cs

然而,现在我想使用我的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类中没有任何iconfigationmanager。我理解这样做的原因是依赖注入,但我仍然没有掌握这一切是如何工作的?

你已经非常接近了,但是你需要修正一些事情。SqlDataAccess实现IConfigManager。为什么?这提供了什么?相反,您应该让它实现一个接口,允许它公开其他类所依赖的功能。

public interface ISqlDataAccess
{
List<T> LoadData<T>(string sql);
int SaveData<T>(string sql, T data);  
}

修改SqlDataAccess类来实现这个接口…

public class SqlDataAccess : ISqlDataAccess

当然,把它和你的DI容器连接起来。

services.AddTransient<ISqlDataAccess, SqlDataAccess>();

现在,任何需要运行SQL的类都可以依赖于ISqlDataAccess接口,利用构造函数注入获得ISqlDataAccess的实例。因为我们已经告诉DI容器在ISqlDataAccess依赖存在时提供一个SqlDataAccess实例,所以它将在你的应用程序中很好地连接起来。

然后我们有ShortUrlProcessor的问题。您将该类声明为静态。这很糟糕,因为它使得它很难使用构造函数注入来获取依赖项,并且任何其他需要调用其方法的类都必须直接调用,而不是通过抽象。这违反了SOLID的依赖倒置原则。由于可维护性和可测试性,我们应该始终努力编写SOLID代码,因此我们需要解决这个问题。

public class ShortUrlProcessor : IShortUrlProcessor
{    
readonly ISqlDataAccess _dataAccess;
public ShortUrlProcessor(ISqlDataAccess dataAccess)
{
_dataAccess = dataAccess;
}

public ShortURLModel GetOriginalURL(string shortUrl)
{        
string sql = $@"SELECT * FROM dbo.shorturl WHERE shortUrl = '{ shortUrl }'";
var originalURLEnum = _dataAccess.LoadData<ShortURLModel>(sql); //<--- problem
return originalURLEnum.First();
}
}

我们还需要一个接口,这样其他类就不必直接依赖于ShortUrlProcessor…

public interface IShortUrlProcessor
{
ShortURLModel GetOriginalURL(string shortUrl);
}

当然,我们还需要把它注册到我们的DI容器中。

services.AddTransient<IShortUrlProcessor, ShortUrlProcessor>();

那么任何需要访问ShortUrlProcessor功能的类都可以通过抽象IShortUrlProcessor来实现。你说过你有一个调用这个的控制器,让我们把它也连接起来。

public class MyController()
{
readonly IShortUrlProcessor _shortUrlProcessor;
public MyController(IShortUrlProcessor shortUrlProcessor)
{
_shortUrlProcessor = shortUrlProcessor;
}
public ActionResult SomeActionMethod()
{
var model = _shortUrlProcessor.GetOriginalURL("asdf");
return View(model);
}
}

我们不需要为控制器创建接口,因为控制器将由框架调用。我们不需要把控制器和DI容器连接起来,因为框架会帮我们处理。

通过做所有这些,我们可以很容易地单独测试单个方法。还有一些改进(我在评论中提到的SQL注入攻击需要修复),但这是朝着正确方向迈出的一大步。

相关内容

  • 没有找到相关文章

最新更新