EFCore Asp.net Core IOC容器

发布于:2025-02-27 ⋅ 阅读:(105) ⋅ 点赞:(0)

分层架构

水平分:把一个操作的执行流程给分成多个类库
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