CSharp: Unit of Work Pattern in donet core 6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Geovin.Du.DuUnitOfWork.Domain
{
/// <summary>
///
/// </summary>
public abstract class Entity
{
/// <summary>
///
/// </summary>
public int Id { get; init; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Geovin.Du.DuUnitOfWork.Domain
{
/// <summary>
/// 工作单元模式 Unit of Work Pattern
/// </summary>
public class Order : Entity
{
/// <summary>
///
/// </summary>
public string Description { get; set; } = string.Empty;
/// <summary>
///
/// </summary>
public string DeliveryAddress { get; set; } = string.Empty;
/// <summary>
///
/// </summary>
public decimal Price { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Geovin.Du.DuUnitOfWork.Domain
{
/// <summary>
/// 工作单元模式 Unit of Work Pattern
/// </summary>
public class Customer : Entity
{
/// <summary>
///
/// </summary>
public string FirstName { get; set; } = string.Empty;
/// <summary>
///
/// </summary>
public string LastName { get; set; } = string.Empty;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Geovin.Du.DuUnitOfWork.Domain;
namespace Geovin.Du.DuUnitOfWork.DuExample.Infrastructure.Repositories.Contracts
{
public interface IRepositoryDu<T>
where T : Entity
{
T Add(T entity);
IEnumerable<T> GetAll();
IEnumerable<T> Get(Expression<Func<T, bool>> predicate);
T GetById(int id);
void Delete(T entity);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Geovin.Du.DuUnitOfWork.DuExample.Infrastructure.Repositories.Contracts;
using Geovin.Du.DuUnitOfWork.Domain;
namespace Geovin.Du.DuUnitOfWork.DuExample.Infrastructure.Repositories
{
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
public class RepositoryDu<T> : IRepositoryDu<T>
where T : Entity
{
protected OrderManagementContextDu _context;
public RepositoryDu(OrderManagementContextDu context)
{
_context = context;
}
public virtual T Add(T entity) =>
_context
.Add(entity)
.Entity;
public virtual IEnumerable<T> GetAll() =>
_context.Set<T>().ToList();
public virtual IEnumerable<T> Get(Expression<Func<T, bool>> predicate) =>
_context.Set<T>()
.AsQueryable()
.Where(predicate)
.ToList();
public virtual T GetById(int id)
{
var entity = _context.Find<T>(id);
return entity ?? throw new ArgumentException($"Entity with {id} doesn't exists");
}
public virtual void Delete(T entity) =>
_context.Remove(entity);
}
}
using Geovin.Du.DuUnitOfWork.DuExample.Infrastructure.Repositories.Contracts;
using Geovin.Du.DuUnitOfWork.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Geovin.Du.DuUnitOfWork.DuExample.Infrastructure
{
/// <summary>
///
/// </summary>
public interface IUnitOfWorkDu
{
IRepositoryDu<Customer> CustomerRepository { get; }
IRepositoryDu<Order> OrderRepository { get; }
void SaveChanges();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Geovin.Du.DuUnitOfWork.Domain;
namespace Geovin.Du.DuUnitOfWork.DuExample.Infrastructure
{
public class OrderManagementContextDu : DbContext
{
public DbSet<Customer> Customers => Set<Customer>();
public DbSet<Order> Orders => Set<Order>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
optionsBuilder.UseSqlite("Data Source=storage1.db");
}
}
using Geovin.Du.DuUnitOfWork.DuExample.Infrastructure.Repositories;
using Geovin.Du.DuUnitOfWork.DuExample.Infrastructure.Repositories.Contracts;
using Geovin.Du.DuUnitOfWork.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Geovin.Du.DuUnitOfWork.DuExample.Infrastructure
{
/// <summary>
///
/// </summary>
public class UnitOfWorkDu : IUnitOfWorkDu
{
private readonly OrderManagementContextDu _context;
private IRepositoryDu<Customer>? _customerRepository;
private IRepositoryDu<Order>? _orderRepository;
public UnitOfWorkDu(OrderManagementContextDu context)
{
_context = context;
}
public IRepositoryDu<Customer> CustomerRepository
{
get
{
if (_customerRepository == null)
{
_customerRepository = new RepositoryDu<Customer>(_context);
}
return _customerRepository;
}
}
public IRepositoryDu<Order> OrderRepository
{
get
{
if (_orderRepository == null)
{
_orderRepository = new RepositoryDu<Order>(_context);
}
return _orderRepository;
}
}
public void SaveChanges() => _context.SaveChanges();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Geovin.Du.DuUnitOfWork.Domain;
using Geovin.Du.DuUnitOfWork.DuExample.Infrastructure;
namespace Geovin.Du.DuUnitOfWork.DuExample.Controllers
{
/// <summary>
///
/// </summary>
public class CustomerControllerDu
{
private readonly IUnitOfWorkDu _unitOfWork;
public CustomerControllerDu(IUnitOfWorkDu unitOfWork)
{
_unitOfWork = unitOfWork;
}
public IEnumerable<Customer> GetAll() => _unitOfWork.CustomerRepository.GetAll();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Geovin.Du.DuUnitOfWork.Domain;
using Geovin.Du.DuUnitOfWork.DuExample.Infrastructure;
namespace Geovin.Du.DuUnitOfWork.DuExample.Controllers
{
/// <summary>
///
/// </summary>
public class OrderControllerDu
{
private readonly IUnitOfWorkDu _unitOfWork;
public OrderControllerDu(IUnitOfWorkDu unitOfWork)
{
_unitOfWork = unitOfWork;
}
public Order Create(int id, string description, string deliveryAddress, decimal price)
{
// ID is usually auto-generated by database.
var newOrder = new Order
{
Id = id,
Description = description,
DeliveryAddress = deliveryAddress,
Price = price,
};
newOrder = _unitOfWork.OrderRepository.Add(newOrder);
// _unitOfWork.CustomerRepository.Add(new Customer() { Id = 33 });
// In this example we work only with order repository,
// but it would be possible to create/update different entities by using
// different repositories and save all changes via unit of work instance.
_unitOfWork.SaveChanges();
return newOrder;
}
public IEnumerable<Order> GetAll() => _unitOfWork.OrderRepository.GetAll();
}
}
/// <summary>
///
/// </summary>
public static class DuExampleExecutor
{
/// <summary>
///
/// </summary>
public static void Execute()
{
ConsoleExtension.WriteSeparator("工作单元模式 Unit of Work Pattern- demo");
InitializeDatabase();
using var context = new OrderManagementContextDu();
var unitOfWork = new UnitOfWorkDu(context);
var customerController = new CustomerControllerDu(unitOfWork);
var orderController = new OrderControllerDu(unitOfWork);
ShowAllCustomers();
ShowAllOrders();
CreateNewOrder();
ShowAllOrders();
void ShowAllCustomers()
{
Console.WriteLine("显示所有客户...");
foreach (var customer in customerController.GetAll())
{
Console.WriteLine($"{customer.FirstName} {customer.LastName}");
}
}
void ShowAllOrders()
{
Console.WriteLine("\n显示所有订单...");
foreach (var order in orderController.GetAll())
{
Console.WriteLine($"{order.Description} 价格为: {order.Price:C}");
}
}
void CreateNewOrder()
{
Console.WriteLine("\n创建新订单...");
orderController.Create(3, "游船 5", "北京 3", 9800);
}
}
/// <summary>
///
/// </summary>
private static void InitializeDatabase()
{
using var context = new OrderManagementContextDu();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var du = new Customer { Id = 1, FirstName = "Du", LastName = "Geovin" };
var tu = new Customer { Id = 2, FirstName = "Tu", LastName = "Juwen" };
var camera = new Order { Id = 1, Description = "摄像机", DeliveryAddress = "深圳 1", Price = 880 };
var phone = new Order { Id = 2, Description = "手机", DeliveryAddress = "上海 2", Price = 210 };
var unitOfWork = new UnitOfWorkDu(context);
unitOfWork.CustomerRepository.Add(du);
unitOfWork.CustomerRepository.Add(tu);
unitOfWork.OrderRepository.Add(camera);
unitOfWork.OrderRepository.Add(phone);
unitOfWork.SaveChanges();
}
}
}
调用:
Geovin.Du.DuUnitOfWork.DuExample.DuExampleExecutor.Execute();
输出:
工作单元模式 Unit of Work Pattern- demo -------------------------------------------------- 显示所有客户... Du Geovin Tu Juwen 显示所有订单... 摄像机 价格为: ¥880.00 手机 价格为: ¥210.00 创建新订单... 显示所有订单... 摄像机 价格为: ¥880.00 手机 价格为: ¥210.00 游船 5 价格为: ¥9800.00
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号