.NET Standard Unit of Work implementation for ADO.NET
LunchPail is a .NET Standard compliant Unit of Work implementation for ADO.NET. The UoW is the workhorse of the data context, so the project was dubbed "lunch pail" as a reference to blue collar athletes.
//startup.cs
public void ConfigureServices(IServiceCollection services)
{
//rest of code...
//context
services.AddTransient<IDbConnectionFactory>(options =>
{
var builder = new SqlConnectionStringBuilder(Configuration.GetConnectionString("DefaultConnection"));
return new DbConnectionFactory(() =>
{
var conn = new SqlConnection(builder.ConnectionString);
conn.Open();
return conn;
});
});
services.AddScoped<IDbContext, DbContext>();
//repositories (we'll add this later)
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
IDbContext
public interface IProductRepository
{
Task<Product> Read (int id);
}
public class ProductRepository : DbRepository
{
public ProductRepository(IDbContext dbContext) : base(dbContext) { }
public Product Read(int id)
{
return Connection.QuerySingleOrDefault<Product>("select * from dbo.Product where Id = @id", new { id }, transaction: Transaction);
}
}
//startup.cs
public void ConfigureServices(IServiceCollection services)
{
//repositories
services.AddScoped<IProductRepository, ProductRepository>();
}
Note the invocation of
dbContext.Commit()
which must occur after every interaction is complete to ensure proper disposal of the connection. This is true whether the interaction is a read or write.
public class ProductService
{
private readonly IDbContext dbContext;
private readonly IProductRepository productRepository;
public ProductService (
IDbContext dbContext,
IProductRepository productRepository)
{
this.dbContext = dbContext;
this.productRepository = productRepository;
}
public Product Read(int id)
{
var product = productRepository.Read(id);
dbContext.Commit(); // You MUST call commit after all interactions
return product;
}
}
Built with ♥ by Pim Brouwers in Toronto, ON.