分层架构
水平分:把一个操作的执行流程给分成多个类库
1软件可以解耦
2便于分工
3便于维护(功能知道出处)
4组件重用
5便于组件替换
6便于功能扩展
7能应对需求的变化
分层
接口层 Learn.NET6.Business.Interfaces
IBaseService
public interface IBaseService
{
#region Query
/// <summary>
/// 根据id查询实体
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
T Find<T>(int id) where T : class;
/// <summary>
/// 提供对单表的查询
/// </summary>
/// <returns>IQueryable类型集合</returns>
[Obsolete("尽量避免使用,using 带表达式目录树的 代替")]
IQueryable<T> Set<T>() where T : class;
/// <summary>
/// 查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="funcWhere"></param>
/// <returns></returns>
IQueryable<T> Query<T>(Expression<Func<T, bool>> funcWhere) where T : class;
/// <summary>
/// 分页查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="S"></typeparam>
/// <param name="funcWhere"></param>
/// <param name="pageSize"></param>
/// <param name="pageIndex"></param>
/// <param name="funcOrderby"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
PageResult<T> QueryPage<T, S>(Expression<Func<T, bool>> funcWhere, int pageSize, int pageIndex, Expression<Func<T, S>> funcOrderby, bool isAsc = true) where T : class;
#endregion
#region Add
/// <summary>
/// 新增数据,即时Commit
/// </summary>
/// <param name="t"></param>
/// <returns>返回带主键的实体</returns>
T Insert<T>(T t) where T : class;
/// <summary>
/// 新增数据,即时Commit
/// 多条sql 一个连接,事务插入
/// </summary>
/// <param name="tList"></param>
IEnumerable<T> Insert<T>(IEnumerable<T> tList) where T : class;
#endregion
#region Update
/// <summary>
/// 更新数据,即时Commit
/// </summary>
/// <param name="t"></param>
void Update<T>(T t) where T : class;
/// <summary>
/// 更新数据,即时Commit
/// </summary>
/// <param name="tList"></param>
void Update<T>(IEnumerable<T> tList) where T : class;
#endregion
#region Delete
/// <summary>
/// 根据主键删除数据,即时Commit
/// </summary>
/// <param name="t"></param>
void Delete<T>(int Id) where T : class;
/// <su+mary>
/// 删除数据,即时Commit
/// </summary>
/// <param name="t"></param>
void Delete<T>(T t) where T : class;
/// <summary>
/// 删除数据,即时Commit
/// </summary>
/// <param name="tList"></param>
void Delete<T>(IEnumerable<T> tList) where T : class;
#endregion
#region Other
/// <summary>
/// 立即保存全部修改
/// 把增/删的savechange给放到这里,是为了保证事务的
/// </summary>
void Commit();
/// <summary>
/// 执行sql 返回集合
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
/// <returns></returns>
IQueryable<T> ExcuteQuery<T>(string sql, SqlParameter[] parameters) where T : class;
/// <summary>
/// 执行sql,无返回
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
void Excute<T>(string sql, SqlParameter[] parameters) where T : class;
#endregion
#region 伪代码
//public void Add();
//public void Update();
//public void Delete();
//public void Query();
#endregion
}
ICommodityService
public interface ICommodityService: IBaseService
{
//public void Add();
//public void Update();
//public void Delete();
//public void Query();
}
ICompanyService
public interface ICompanyService : IBaseService
{
public void DeleteCompanyAndUser();
}
服务层 Learn.NET6.Business.Services
BaseService
public abstract class BaseService : IBaseService
{
protected DbContext Context { get; set; }
/// <summary>
///
/// </summary>
/// <param name="context"></param>
public BaseService(DbContext context)
{
Console.WriteLine($"{this.GetType().FullName}被构造....");
Context = context;
}
#region Query
public T Find<T>(int id) where T : class
{
return this.Context.Set<T>().Find(id);
}
/// <summary>
/// 不应该暴露给上端使用者,尽量少用
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
//[Obsolete("尽量避免使用,using 带表达式目录树的代替")]
public IQueryable<T> Set<T>() where T : class
{
return this.Context.Set<T>();
}
/// <summary>
/// 这才是合理的做法,上端给条件,这里查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="funcWhere"></param>
/// <returns></returns>
public IQueryable<T> Query<T>(Expression<Func<T, bool>> funcWhere) where T : class
{
return this.Context.Set<T>().Where<T>(funcWhere);
}
public PageResult<T> QueryPage<T, S>(Expression<Func<T, bool>> funcWhere, int pageSize, int pageIndex, Expression<Func<T, S>> funcOrderby, bool isAsc = true) where T : class
{
var list = Set<T>();
if (funcWhere != null)
{
list = list.Where<T>(funcWhere);
}
if (isAsc)
{
list = list.OrderBy(funcOrderby);
}
else
{
list = list.OrderByDescending(funcOrderby);
}
PageResult<T> result = new PageResult<T>()
{
DataList = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(),
PageIndex = pageIndex,
PageSize = pageSize,
TotalCount = list.Count()
};
return result;
}
#endregion
#region Insert
/// <summary>
/// 即使保存 不需要再Commit
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
public T Insert<T>(T t) where T : class
{
this.Context.Set<T>().Add(t);
this.Commit();//写在这里 就不需要单独commit 不写就需要
return t;
}
public IEnumerable<T> Insert<T>(IEnumerable<T> tList) where T : class
{
this.Context.Set<T>().AddRange(tList);
this.Commit();//一个链接 多个sql
return tList;
}
#endregion
#region Update
/// <summary>
/// 是没有实现查询,直接更新的,需要Attach和State
///
/// 如果是已经在context,只能再封装一个(在具体的service)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
public void Update<T>(T t) where T : class
{
if (t == null) throw new Exception("t is null");
this.Context.Set<T>().Attach(t);//将数据附加到上下文,支持实体修改和新实体,重置为UnChanged
this.Context.Entry<T>(t).State = EntityState.Modified;
this.Commit();//保存 然后重置为UnChanged
}
public void Update<T>(IEnumerable<T> tList) where T : class
{
foreach (var t in tList)
{
this.Context.Set<T>().Attach(t);
this.Context.Entry<T>(t).State = EntityState.Modified;
}
this.Commit();
}
#endregion
#region Delete
/// <summary>
/// 先附加 再删除
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
public void Delete<T>(T t) where T : class
{
if (t == null) throw new Exception("t is null");
this.Context.Set<T>().Attach(t);
this.Context.Set<T>().Remove(t);
this.Commit();
}
/// <summary>
/// 还可以增加非即时commit版本的,
/// 做成protected
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="Id"></param>
public void Delete<T>(int Id) where T : class
{
T t = this.Find<T>(Id);//也可以附加
if (t == null) throw new Exception("t is null");
this.Context.Set<T>().Remove(t);
this.Commit();
}
public void Delete<T>(IEnumerable<T> tList) where T : class
{
foreach (var t in tList)
{
this.Context.Set<T>().Attach(t);
}
this.Context.Set<T>().RemoveRange(tList);
this.Commit();
}
#endregion
#region Other
public void Commit()
{
this.Context.SaveChanges();
}
public IQueryable<T> ExcuteQuery<T>(string sql, SqlParameter[] parameters) where T : class
{
return null;
}
public void Excute<T>(string sql, SqlParameter[] parameters) where T : class
{
IDbContextTransaction trans = null;
//DbContextTransaction trans = null;
try
{
trans = this.Context.Database.BeginTransaction();
//this.Context.Database.ExecuteSqlRaw(sql, parameters);
trans.Commit();
}
catch (Exception)
{
if (trans != null)
trans.Rollback();
throw;
}
}
public virtual void Dispose()
{
if (this.Context != null)
{
this.Context.Dispose();
}
}
#endregion
#region 伪代码
//private CustomerDbContext Context = new CustomerDbContext();
//public void Add()
//{
// //Context.Companies.Add;
// //Context.SaveChanges();
//}
//public void Delete()
//{
// throw new NotImplementedException();
//}
//public void Qeury()
//{
// throw new NotImplementedException();
//}
//public void Update()
//{
// throw new NotImplementedException();
//}
#endregion
}
CommodityService
public class CommodityService : BaseService, ICommodityService
{
public CommodityService(DbContext context) : base(context)
{
}
}
CompanyService
public class CompanyService : BaseService, ICompanyService
{
public CompanyService(DbContext context) : base(context)
{
}
public void DeleteCompanyAndUser()
{
}
}
UI 层
public class EighthController : Controller
{
private readonly ILogger<EighthController> _logger;
private readonly ICommodityService _ICommodityService;
public EighthController(ILogger<EighthController> logger, ICommodityService iCommodityService)
{
_logger = logger;
this._ICommodityService = iCommodityService;
}
/// <summary>
/// 关于分层:
/// 1.UI层:Learn.NET6.Project
/// 2.数据访问层:Learn.NET6.EFCore.DB
/// 3.业务逻辑层:Learn.NET6.Business.Services
///
/// 案例:查询Commodity—UI—业务逻辑层—数据访问层
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
//CustomerDbContext context = new CustomerDbContext();
//Commodity commodity = context.Commodities.FirstOrDefault();
//ICommodityService commodityService = new CommodityService(new CustomerDbContext());
//List<Commodity> commodities = commodityService.Query<Commodity>(c => true).ToList();
List<Commodity> commodities = _ICommodityService.Query<Commodity>(c => true).ToList();
return View(commodities);
}
}
@using Learn.NET6.EFCore.DB.Models;
@model List<Commodity>
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
@foreach(Commodity commodity in Model)
{
<h3>@commodity.Title</h3>
}
注册
#region 使用Autofac
{
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>((context, buider) =>
{
buider.RegisterType<Microphone>().As<IMicrophone>();
buider.RegisterType<CommodityService>().As<ICommodityService>();
buider.RegisterType<CompanyService>().As<ICompanyService>();
//buider.RegisterType<CustomerDbContext>().As<DbContext>();
});
}
#endregion
#region EFCore6 整合ASP.NET Core6.0
builder.Services.AddTransient<DbContext, CustomerDbContext>();
#endregion