我需要使用默认用户为应用程序数据库设定种子。我在这个项目中没有使用实体框架,我决定改用 Dapper 。
我能做的最简单的事情就是使用DatabaseConfig
(或AccountsConfig
)这样的简单类,并使用Seed()
静态方法:
public class DatabaseConfig {
public static void Seed() {
using(var conn = new SqlConnection()) {
conn.ConnectionString = GetConnectionString();
conn.Open();
var query = "insert into users (username, [password]) values (@username, @password)";
var queryParams = new {
username = "Admin",
password = HashedPassword.CreateHash("DefaultSecretKey")
}
conn.Execute(query, queryParams);
}
}
private static string GetConnectionString() {
return ConfigurationManager.ConnectionStrings["appDb"].ConnectionString;
}
}
然后在 Global.asax :
中调用它DatabaseConfig.Seed();
我有两个依赖项:
我调用ConfigurationManager
来获取连接字符串。我不知道这是不是一个坏方法。对于我在应用程序中使用的其他服务,我将连接字符串作为 SimpleInjector 初始值设定项中的构造函数参数传递:
private static void InitializeContainer(Container container) {
var appDbConnString = ConfigurationManager.ConnectionStrings["appDb"].ConnectionString;
container.RegisterSingleton<IUsersRepository>(new UsersRepository(appDbConnString));
}
另一个依赖是HashedPassword
类。我不希望它随着时间的推移而改变,但这仍然是一种依赖。我应该解决吗?我该如何解决?
答案 0 :(得分:4)
我调用ConfigurationManager来获取连接字符串。我不知道这是不是一个坏方法。
通常,您应该只在应用程序启动时读取配置文件,最好只在应用程序的启动路径中读取。这允许将配置文件的读取集中在一个单独的位置,并且允许应用程序在缺少某些配置值的情况下快速失败。
你似乎遵循这种做法,所以我会说你正在做的事情很好。
另一个依赖是HashedPassword类。我不希望它随着时间而改变,但仍然是一种依赖。我应该解决吗?
由于此Seed
方法似乎是组合根的一部分,因此可以对系统中的其他类具有强依赖性。或者让我换一种说法,如果使用这种依赖关系不会以任何方式造成麻烦(因为你不想孤立地测试代码,或者想要替换,包装,装饰器或拦截该类中的代码) ),我会说这没关系。
但是,如果您希望此HashesPassword
类可注入,则必须使其成为实例类。在这种情况下,您应该将其隐藏在抽象(例如IHashPashword
)后面并将其作为参数传递到Seed()
方法中,或者您应该将DatabaseConfig
提升为非静态类非静态方法并将IHashPashword
抽象注入其构造函数中。这允许您从容器中解析DatabaseConfig
。
答案 1 :(得分:1)
您正在以静态方式访问HashedPassword和ConfigurationManager,这意味着您需要将它们更改为非静态类,以便依赖注入它们。可以通过更改它们来完成(这可能是不可能的,因为它们不是您的类)或将它们包装在实例类中。