仓储层的定义
源码及系列文章目录
Git 源码 :https://github.com/tangsong1995/TS.Microservices
CSDN 资源 :https://download.csdn.net/download/qq_33649351/34675095
系列文章目录 :https://blog.csdn.net/qq_33649351/article/details/120998558
IRepository
定义 IRepository 接口:
public interface IRepository<TEntity> where TEntity : Entity, IAggregateRoot
{
IUnitOfWork UnitOfWork { get; }
TEntity Add(TEntity entity);
Task<TEntity> AddAsync(TEntity entity, CancellationToken cancellationToken = default);
TEntity Update(TEntity entity);
Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);
bool Remove(Entity entity);
Task<bool> RemoveAsync(Entity entity);
}
public interface IRepository<TEntity, TKey> : IRepository<TEntity> where TEntity : Entity<TKey>, IAggregateRoot
{
bool Delete(TKey id);
Task<bool> DeleteAsync(TKey id, CancellationToken cancellationToken = default);
TEntity Get(TKey id);
Task<TEntity> GetAsync(TKey id, CancellationToken cancellationToken = default);
}
接口约束了 TEntity 泛型为 Entity 类型,并且实现了 IAggregateRoot 聚合根。
接口同时定义了包含普通实体和包含指定主键实体的方法。
接口定义了 IUnitOfWork 属性,用来获取 UnitOfWork 对象;接口定义了一些通用的增删改查基本方法。
Repository
public abstract class Repository<TEntity, TDbContext> : IRepository<TEntity> where TEntity : Entity, IAggregateRoot where TDbContext : EFContext
{
protected virtual TDbContext DbContext { get; set; }
public Repository(TDbContext context)
{
this.DbContext = context;
}
public virtual IUnitOfWork UnitOfWork => DbContext;
public virtual TEntity Add(TEntity entity)
{
return DbContext.Add(entity).Entity;
}
public virtual Task<TEntity> AddAsync(TEntity entity, CancellationToken cancellationToken = default)
{
return Task.FromResult(Add(entity));
}
public virtual TEntity Update(TEntity entity)
{
return DbContext.Update(entity).Entity;
}
public virtual Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
{
return Task.FromResult(Update(entity));
}
public virtual bool Remove(Entity entity)
{
DbContext.Remove(entity);
return true;
}
public virtual Task<bool> RemoveAsync(Entity entity)
{
return Task.FromResult(Remove(entity));
}
}
public abstract class Repository<TEntity, TKey, TDbContext> : Repository<TEntity, TDbContext>, IRepository<TEntity, TKey> where TEntity : Entity<TKey>, IAggregateRoot where TDbContext : EFContext
{
public Repository(TDbContext context) : base(context)
{
}
public virtual bool Delete(TKey id)
{
var entity = DbContext.Find<TEntity>(id);
if (entity == null)
{
return false;
}
DbContext.Remove(entity);
return true;
}
public virtual async Task<bool> DeleteAsync(TKey id, CancellationToken cancellationToken = default)
{
var entity = await DbContext.FindAsync<TEntity>(id, cancellationToken);
if (entity == null)
{
return false;
}
DbContext.Remove(entity);
return true;
}
public virtual TEntity Get(TKey id)
{
return DbContext.Find<TEntity>(id);
}
public virtual async Task<TEntity> GetAsync(TKey id, CancellationToken cancellationToken = default)
{
return await DbContext.FindAsync<TEntity>(id, cancellationToken);
}
}
Repository的具体实现依赖了 EFContext ,关于 EFContext 的实现请参考:工作单元模式
实现具体的仓储
为领域模型定义DomainContext
定义 OrderingContext 继承 EFContext:
public class OrderingContext : EFContext
{
public OrderingContext(DbContextOptions options, IMediator mediator) : base(options, mediator)
{
}
public DbSet<Order> Orders { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
#region 注册领域模型与数据库的映射关系
modelBuilder.ApplyConfiguration(new OrderEntityTypeConfiguration());
#endregion
base.OnModelCreating(modelBuilder);
}
}
在 OnModelCreating 重载方法中注册领域模型与数据库的映射关系,具体的映射关系由 OrderEntityTypeConfiguration 实现:
class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Order>
{
public void Configure(EntityTypeBuilder<Order> builder)
{
builder.HasKey(p => p.Id);
builder.ToTable("order");
builder.Property(p => p.UserId).HasMaxLength(20);
builder.Property(p => p.UserName).HasMaxLength(30);
//导航属性
builder.OwnsOne(o => o.Address, a =>
{
a.WithOwner();
a.Property(p => p.City).HasMaxLength(20);
a.Property(p => p.Street).HasMaxLength(50);
a.Property(p => p.ZipCode).HasMaxLength(10);
});
}
}
OrderEntityTypeConfiguration 继承了 IEntityTypeConfiguration,通过 Configure 方法实现属性与数据库具体字段的映射;HasKey 指定主键,HasMaxLength 指定数据库字段长度,通过 OwnsOne 配置导航属性。
为领域模型定义TransactionBehavior实现事务处理
定义 OrderingContextTransactionBehavior 继承 TransactionBehavior :
public class OrderingContextTransactionBehavior<TRequest, TResponse> : TransactionBehavior<OrderingContext, TRequest, TResponse>
{
public OrderingContextTransactionBehavior(OrderingContext dbContext, ILogger<OrderingContextTransactionBehavior<TRequest, TResponse>> logger, ICapPublisher capBus) : base(dbContext, logger,capBus)
{
}
}
注册Mysql
public static IServiceCollection AddDomainContext(this IServiceCollection services, Action<DbContextOptionsBuilder> optionsAction)
{
return services.AddDbContext<OrderingContext>(optionsAction);
}
public static IServiceCollection AddMySqlDomainContext(this IServiceCollection services, string connectionString)
{
return services.AddDomainContext(builder =>
{
builder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
});
}
在 ConfigureServices 中进行注册:
services.AddMySqlDomainContext(Configuration.GetValue<string>("Mysql"));
使用 DbContext 的 Database 属性的 EnsureCreated 方法确保数据库被创建:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
using (var scope = app.ApplicationServices.CreateScope())
{
var context = scope.ServiceProvider.GetService<OrderingContext>();
context.Database.EnsureCreated();
}
}
实现仓储层
定义 IOrderRepository 继承 IRepository<TEntity, TKey> :
public interface IOrderRepository : IRepository<Order, long>
{
}
定义 OrderRepository 实现 Repository<TEntity, TKey, TDbContext> 和 IOrderRepository :
public class OrderRepository : Repository<Order, long, OrderingContext>, IOrderRepository
{
public OrderRepository(OrderingContext context) : base(context)
{
}
}