Reputation: 2973
I need to seed the application database with default users. I don't use Entity Framework in this project, I've decided to use Dapper instead.
Simplest thing that I can do is to have a simple class like DatabaseConfig
(or AccountsConfig
) with a Seed()
static method:
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;
}
}
and then to call it in the Global.asax:
DatabaseConfig.Seed();
I have two dependencies here:
I call a ConfigurationManager
to get a connection string. I don't know if this is a bad approach. For other services I use in the application I pass the connection strings as a constructor parameters in the SimpleInjector initializer:
private static void InitializeContainer(Container container) {
var appDbConnString = ConfigurationManager.ConnectionStrings["appDb"].ConnectionString;
container.RegisterSingleton<IUsersRepository>(new UsersRepository(appDbConnString));
}
The other dependency is HashedPassword
class. I don't expect it to change with time but still this is a dependency. Should I resolve it? How do I resolve it?
Upvotes: 2
Views: 748
Reputation: 172825
I call a ConfigurationManager to get a connection string. I don't know if this is a bad approach.
In general, you should only read the config file at application startup, and preferably only within the startup path of the application. This allows the reading of the config file to be centralized in one single place and it allows the application to fail fast in case some configuration value is missing.
You seem to follow that practice, so I would say what you're doing is fine.
The other dependency is HashedPassword class. I don't expect it to change with time but still this is a dependency. Should I resolve it?
Since this Seed
method seems to be part of your composition root, it's okay to have strong dependencies on other classes in your system. Or let me put it differently, if the use of this dependency doesn't cause trouble in any way (because you don't want to test the code in isolation, or want to replace, wrap, decorator or intercept the code inside that class), I would say this is okay.
If however you want this HashesPassword
class to be injectable, you will have to make it an instance class. In that case you should probably hide it behind an abstraction (like IHashPashword
) and pass it as parameter into the Seed()
method, or you should promote the DatabaseConfig
to a non-static class with non-static methods and inject the IHashPashword
abstraction into its constructor. This allows you to resolve DatabaseConfig
from the container.
Upvotes: 4
Reputation: 410
you are accessing HashedPassword and ConfigurationManager in static way, this means you need to change them to non static classes in order to dependency inject them. that can be done by changing them (which may be not possible is they are not your classes) or to wrap them in an instance class.
Upvotes: 1