I just finished the Pluralsight courses about Inversion of Control and Mirco-ORMs, and I am struggling with the implementation aspect of some of the concepts.
This is my (simplified) repository implementation using Dapper:
public class AppRepository : IAppRepository
{
public string TableName { get; } = "apps";
private IDbConnection _db;
public AppRepository(IDbConnection db = null)
{
if (db == null)
_db = Bootstrap.container.Resolve<IDbConnection>(); // Default: connection from the simple injector container
else
_db = db;
}
public List<App> GetAll() => _db.Query<App>(QueryBuilder.BuildGetAll(TableName)).ToList();
}
QueryBuilder
is a static class, shared among all repositories, which creates the different sql strings.
The Bootstrap
class exposes a UnityContainer
:
public static class Bootstrap
{
public static UnityContainer container;
private static IDbConnection _db;
public static void Start(string connectionStringId)
{
container = new UnityContainer();
_db = GetDbConnection(connectionStringId);
// Register your types:
container.RegisterInstance<IDbConnection>(_db);
}
public static IDbConnection GetDbConnection(string connectionStringId)
{
var connectionString = ConfigurationManager.ConnectionStrings[connectionStringId].ConnectionString;
IDbConnection db = new MySqlConnection(connectionString);
return db;
}
}
Then I read a post about NOT to use this kind of pattern:
by far the most common IoC mistake is to wrap up the container in a public static or singleton class that is referenced throughout the code base. It is important to realize that this is not dependency injection, it is service location which is widely regarded as an anti-pattern. I cannot over-emphasize how important it is to move away from this design and to inject your dependencies from the root of your application. In fact, virtually all other IoC mistakes come about as a direct result of this misunderstanding.
I've used IDbConnection db = null
because 99% of the time I will be using a single thread with a single connection, but the other 1% I will be transfering data from one server to another.
I have ~60 models (60 tables), so constantly injecting the IDbConnection
connection seems like a hassle, specially if further down the path I have to change it somehow. At the same time, Unity is doing nothing useful at this point in time. I could just let the connection be a public property of the static Bootstrap
class. I've read some opinions about injectors being more more annoying than helpful.
For the moment I am building a console application, and in the Main
function there is a Bootstrap.Start()
that lets me forget about IDbConnection
for the rest of the code.
I've been trying to find some examples with good patters using Dapper + dependency injection, but I haven't found anything yet that clarifies my doubts.