.Net Core2.2 + EF Core + DI,三层框架项目搭建教程

笔记:html

  近两年.Net Core发展的很快,目前最新版为3.0预览版,以前在网上买了一本1.1版书籍都还没来得及看呢,估计如今拿出来看也毫无心义了。已多年.net工做经验,看书不如直接实际上手来得快,遇到问题再度娘吧。正好最近公司不忙时,抽空亲手搭建.Net Core项目熟悉一下,提及.net那最自豪的就是VS编译器了,强大的辅助功能不少中小型项目只须要下一步就能够建立完成。这里咱们还须要简单封装一下,使用仓储模式对数据访问层封装和Service层封装,经过.net自带DI依赖注入进行建立对象。对于初学者的我只能简单的封装一下,接下来我会一一讲解框架的思路,若有更好的方案或不明的地方欢迎留言。转载请备注来源:http://www.javashuo.com/article/p-gtxzjzew-hq.html数据库

下面是已搭建好的框架结构:json

 

第一步:建立解决方案app

使用Visual Studio 2019编译器建立解决方案,默认安装vs2019自带的.NET Core 2.1,建立.NET Core 2.2版须要下载SDK安装。框架

https://dotnet.microsoft.com/download/visual-studio-sdks?utm_source=getdotnetsdk&utm_medium=referralide

接下来能够建立项目了,首先建立的是数据访问层,咱们命名为common.Core,另外给他建立一个接口层common.Interface。函数

 

(注意全部程序集建立必须为.Net Core版,为之后发布垮平台考虑)工具

第二步:建立Model层visual-studio

封装仓储层以前先来建立数据Model层,Nuget添加EF Core相关引用,工具 - NuGet包管理器 - 程序包管理器控制台,默认项目选择Model程序集依次安装如下组件包。ui

Install-Package Microsoft.EntityFrameworkCore -version 2.2.4

Install-Package Microsoft.EntityFrameworkCore.SqlServer -version 2.2.4

Install-Package Microsoft.EntityFrameworkCore.Tools -version 2.2.4

也能够在项目中找到依赖项,右键管理NuGet管理包方式进行添加。

 

Microsoft.EntityFrameworkCore.Tools中包含了Microsoft.EntityFrameworkCore.Design依赖包,不须要单独安装了。

这里我使用的是Database First模式,使用工具Scaffold-DbContext(数据库上下文脚手架)来生成model类文件和DbContext。

执行如下命令:-o (OutputDir) 指定用于输出类的目录  -f (Force) 生成时覆盖现有文件 -Context 指定生成的DbContext类的名称,省略的话按数据库名称生成DbContext类文件。

Scaffold-DbContext "server=.;database=ConCard;uid=sa;pwd=123123;" Microsoft.EntityFrameworkCore.SqlServer -O Models -F

出现错误:VS2019有个小小BUG,默认项目选中之后最终执行的不是被选中程序集,这里须要把model程序集设为启动项目,再次执行。

自动生成全部类模型文件,ConCardContext.cs数据库上下文也都帮你建立好了,这样就省去了咱们手动写DBSet时间。

第三步:封装数据访问层

数据访问层主要封装仓储Repository和工做单元UnitOfWork,我把这两个合并到一个类中实现,经过简单工厂方式建立实例对象。

咱们直接把ConCardContext.cs这个类复制到common.Core程序集中,把命名空间修改成common.Core。

这时应该报错,由于common.Core项目中没有引用EFCore依赖包,按以前Model层添加同样,使用Install-Package命令为common.Core添加依赖包,Tools能够不用安装。

依赖项中,右键添加引用,把Model和common.Interface项目引用,ConCardContext.cs中using model就不会报错了。

接下来修改下ConCardContext:

重写SaveChanges()方法

public override int SaveChanges()
{
    return base.SaveChanges(true);
}

删除OnConfiguring()方法,由于咱们不须要在这里配置数据库链接,后面经过读取配置方式设置。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        optionsBuilder.UseSqlServer("server=.;database=ConCard;uid=sa;pwd=123123;");
     }
}

common.Interface程序集中建立IconcardContext接口,ConCardContext类中继承自这个接口。(主要用来后期使用DI依赖注入使用,不用接口也能够用DbContext代替)

ConCardContext类:

using System;
using com.Synjones.Model.Models;
using common.Interface;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace common.Core
{
    public partial class ConCardContext : DbContext, IconcardContext
    {
        public ConCardContext()
        {
        }

        public ConCardContext(DbContextOptions<ConCardContext> options)
            : base(options)
        {
        }

        public override int SaveChanges()
        {
            return base.SaveChanges(true);
        }

        public virtual DbSet<Admin> Admin { get; set; }
        public virtual DbSet<User> User { get; set; }


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");

            modelBuilder.Entity<Admin>(entity =>
            {
                entity.Property(e => e.PassWord).HasMaxLength(50);

                entity.Property(e => e.UserId).HasMaxLength(50);
            });

            modelBuilder.Entity<User>(entity =>
            {
                entity.Property(e => e.Name).HasMaxLength(50);

                entity.Property(e => e.Phone).HasMaxLength(50);
            });
        }
    }
}
View Code

开始继续建立Repository.cs仓储类,它是一个泛型类,而且拥有一个带有参数的构造方法,经过构造方法得到当前DbContext上下文对象,泛型类为指定Model类型,经过DbContext.Set<T>()方法最终获得相应的DbSet<T>对象来操做工做单元。

固然咱们也要给他定义一个接口IRepository接口:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace common.Interface
{
    public interface IRepository<T> : IDisposable where T : class
    {
        /// <summary>
        /// 显式开启数据上下文事务
        /// </summary>
        /// <param name="isolationLevel">指定链接的事务锁定行为</param>
        void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified);

        /// <summary>
        /// 提交事务的更改
        /// </summary>
        void Commit();

        /// <summary>
        /// 显式回滚事务,仅在显式开启事务后有用
        /// </summary>
        void Rollback();

        /// <summary>
        /// 提交当前单元操做的更改
        /// </summary>
        int SaveChanges();

        /// <summary>
        /// 获取 当前实体类型的查询数据集,数据将使用不跟踪变化的方式来查询,当数据用于展示时,推荐使用此数据集,若是用于新增,更新,删除时,请使用<see cref="TrackEntities"/>数据集
        /// </summary>
        IQueryable<T> Entities { get; }

        /// <summary>
        /// 获取 当前实体类型的查询数据集,当数据用于新增,更新,删除时,使用此数据集,若是数据用于展示,推荐使用<see cref="Entities"/>数据集
        /// </summary>
        IQueryable<T> TrackEntities { get; }

        /// <summary>
        /// 插入 - 经过实体对象添加
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="isSave">是否执行</param>
        /// /// <returns></returns>
        T Add(T entity, bool isSave = true);

        /// <summary>
        /// 批量插入 - 经过实体对象集合添加
        /// </summary>
        /// <param name="entitys">实体对象集合</param>
        /// <param name="isSave">是否执行</param>
        void AddRange(IEnumerable<T> entitys, bool isSave = true);

        /// <summary>
        /// 删除 - 经过实体对象删除
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="isSave">是否执行</param>
        void Delete(T entity, bool isSave = true);

        /// <summary>
        /// 批量删除 - 经过实体对象集合删除
        /// </summary>
        /// <param name="entitys">实体对象集合</param>
        /// <param name="isSave">是否执行</param>
        void Delete(bool isSave = false, params T[] entitys);

        /// <summary>
        /// 删除 - 经过主键ID删除
        /// </summary>
        /// <param name="id">主键ID</param>
        /// <param name="isSave">是否执行</param>
        void Delete(object id, bool isSave = true);

        /// <summary>
        /// 批量删除 - 经过条件删除
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <param name="isSave">是否执行</param>
        void Delete(Expression<Func<T, bool>> @where, bool isSave = true);

        /// <summary>
        /// 修改 - 经过实体对象修改
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="isSave"></param>
        void Update(T entity, bool isSave = true);

        /// <summary>
        /// 批量修改 - 经过实体对象集合修改
        /// </summary>
        /// <param name="entitys">实体对象集合</param>
        /// <param name="isSave"></param>
        void Update(bool isSave = true, params T[] entitys);

        /// <summary>
        /// 是否知足条件
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        bool Any(Expression<Func<T, bool>> @where);

        /// <summary>
        /// 返回总条数
        /// </summary>
        /// <returns></returns>
        int Count();

        /// <summary>
        /// 返回总条数 - 经过条件过滤
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        int Count(Expression<Func<T, bool>> @where);

        /// <summary>
        /// 返回第一条记录
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        T FirstOrDefault(Expression<Func<T, bool>> @where);

        /// <summary>
        /// 返回第一条记录 - 经过条件过滤
        /// </summary>
        /// <typeparam name="TOrder">排序约束</typeparam>
        /// <param name="where">过滤条件</param>
        /// <param name="order">排序条件</param>
        /// <param name="isDesc">排序方式</param>
        /// <returns></returns>
        T FirstOrDefault<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, bool isDesc = false);

        /// <summary>
        /// 去重查询
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        IQueryable<T> Distinct(Expression<Func<T, bool>> @where);

        /// <summary>
        /// 条件查询
        /// </summary>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        IQueryable<T> Where(Expression<Func<T, bool>> @where);

        /// <summary>
        /// 条件查询 - 支持排序
        /// </summary>
        /// <typeparam name="TOrder">排序约束</typeparam>
        /// <param name="where">过滤条件</param>
        /// <param name="order">排序条件</param>
        /// <param name="isDesc">排序方式</param>
        /// <returns></returns>
        IQueryable<T> Where<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, bool isDesc = false);

        /// <summary>
        /// 条件分页查询 - 支持排序
        /// </summary>
        /// <typeparam name="TOrder">排序约束</typeparam>
        /// <param name="where">过滤条件</param>
        /// <param name="order">排序条件</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页记录条数</param>
        /// <param name="count">返回总条数</param>
        /// <param name="isDesc">是否倒序</param>
        /// <returns></returns>
        IEnumerable<T> Where<TOrder>(Func<T, bool> @where, Func<T, TOrder> order, int pageIndex, int pageSize, out int count, bool isDesc = false);

        /// <summary>
        /// 条件分页查询 - 支持排序 - 支持Select导航属性查询
        /// </summary>
        /// <typeparam name="TOrder">排序约束</typeparam>
        /// <param name="where">过滤条件</param>
        /// <param name="order">排序条件</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页记录条数</param>
        /// <param name="count">返回总条数</param>
        /// <param name="isDesc">是否倒序</param>
        /// <returns></returns>
        IQueryable<T> Where<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, int pageIndex, int pageSize, out int count, bool isDesc = false);

        /// <summary>
        /// 获取全部数据
        /// </summary>
        /// <returns></returns>
        IQueryable<T> GetAll();

        /// <summary>
        /// 获取全部数据 - 支持排序
        /// </summary>
        /// <typeparam name="TOrder">排序约束</typeparam>
        /// <param name="order">排序条件</param>
        /// <param name="isDesc">排序方式</param>
        /// <returns></returns>
        IQueryable<T> GetAll<TOrder>(Expression<Func<T, TOrder>> order, bool isDesc = false);

        /// <summary>
        /// 根据ID查询
        /// </summary>
        /// <typeparam name="Ttype">字段类型</typeparam>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        T GetById<Ttype>(Ttype id);

        /// <summary>
        /// 获取最大值
        /// </summary>
        /// <typeparam name="Ttype">字段类型</typeparam>
        /// <param name="column">字段条件</param>
        /// <returns></returns>
        Ttype Max<Ttype>(Expression<Func<T, Ttype>> column);

        /// <summary>
        /// 获取最大值
        /// </summary>
        /// <typeparam name="Ttype">字段类型</typeparam>
        /// <param name="column">字段条件</param>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        Ttype Max<Ttype>(Expression<Func<T, Ttype>> column, Expression<Func<T, bool>> @where);

        /// <summary>
        /// 获取最小值
        /// </summary>
        /// <typeparam name="Ttype">字段类型</typeparam>
        /// <param name="column">字段条件</param>
        /// <returns></returns>
        Ttype Min<Ttype>(Expression<Func<T, Ttype>> column);

        /// <summary>
        /// 获取最小值
        /// </summary>
        /// <typeparam name="Ttype">字段类型</typeparam>
        /// <param name="column">字段条件</param>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        Ttype Min<Ttype>(Expression<Func<T, Ttype>> column, Expression<Func<T, bool>> @where);

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <typeparam name="TType">字段类型</typeparam>
        /// <param name="selector">字段条件</param>
        /// <param name="where">过滤条件</param>
        /// <returns></returns>
        TType Sum<TType>(Expression<Func<T, TType>> selector, Expression<Func<T, bool>> @where) where TType : new();
    }
}
View Code

Repository类,实现了CRUD基本功能的封装:

using common.Interface;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace common.Core
{
    public class Repository<T> : IRepository<T> where T : class
    {
        private ConCardContext _dbContext;
        private readonly DbSet<T> _dbSet;
        private readonly string _connStr;

        public Repository(IconcardContext mydbcontext)
        {
            this._dbContext = mydbcontext as ConCardContext;
            this._dbSet = _dbContext.Set<T>();
            this._connStr = _dbContext.Database.GetDbConnection().ConnectionString;
        }

        public void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified)
        {
            if (this._dbContext.Database.CurrentTransaction == null)
            {
                this._dbContext.Database.BeginTransaction(isolationLevel);
            }
        }

        public void Commit()
        {
            var transaction = this._dbContext.Database.CurrentTransaction;
            if (transaction != null)
            {
                try
                {
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }

        public void Rollback()
        {
            if (this._dbContext.Database.CurrentTransaction != null)
            {
                this._dbContext.Database.CurrentTransaction.Rollback();
            }
        }

        public int SaveChanges()
        {
            return this._dbContext.SaveChanges();
        }


        public IQueryable<T> Entities
        {
            get { return this._dbSet.AsNoTracking(); }
        }

        public IQueryable<T> TrackEntities
        {
            get { return this._dbSet; }
        }

        public T Add(T entity, bool isSave = true)
        {
            this._dbSet.Add(entity);
            if (isSave)
            {
                this.SaveChanges();
            }
            return entity;
        }

        public void AddRange(IEnumerable<T> entitys, bool isSave = true)
        {
            this._dbSet.AddRange(entitys);
            if (isSave)
            {
                this.SaveChanges();
            }
        }

        public void Delete(T entity, bool isSave = true)
        {
            this._dbSet.Remove(entity);
            if (isSave)
            {
                this.SaveChanges();
            }
        }

        public void Delete(bool isSave = true, params T[] entitys)
        {
            this._dbSet.RemoveRange(entitys);
            if (isSave)
            {
                this.SaveChanges();
            }
        }

        public void Delete(object id, bool isSave = true)
        {
            this._dbSet.Remove(this._dbSet.Find(id));
            if (isSave)
            {
                this.SaveChanges();
            }
        }

        public void Delete(Expression<Func<T, bool>> @where, bool isSave = true)
        {
            T[] entitys = this._dbSet.Where<T>(@where).ToArray();
            if (entitys.Length > 0)
            {
                this._dbSet.RemoveRange(entitys);
            }
            if (isSave)
            {
                this.SaveChanges();
            }
        }

        public void Update(T entity, bool isSave = true)
        {
            var entry = this._dbContext.Entry(entity);
            if (entry.State == EntityState.Detached)
            {
                entry.State = EntityState.Modified;
            }
            if (isSave)
            {
                this.SaveChanges();
            }
        }

        public void Update(bool isSave = true, params T[] entitys)
        {
            var entry = this._dbContext.Entry(entitys);
            if (entry.State == EntityState.Detached)
            {
                entry.State = EntityState.Modified;
            }
            if (isSave)
            {
                this.SaveChanges();
            }
        }

        public bool Any(Expression<Func<T, bool>> @where)
        {
            return this._dbSet.AsNoTracking().Any(@where);
        }

        public int Count()
        {
            return this._dbSet.AsNoTracking().Count();
        }

        public int Count(Expression<Func<T, bool>> @where)
        {
            return this._dbSet.AsNoTracking().Count(@where);
        }

        public T FirstOrDefault(Expression<Func<T, bool>> @where)
        {
            return this._dbSet.AsNoTracking().FirstOrDefault(@where);
        }

        public T FirstOrDefault<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, bool isDesc = false)
        {
            if (isDesc)
            {
                return this._dbSet.AsNoTracking().OrderByDescending(order).FirstOrDefault(@where);
            }
            else
            {
                return this._dbSet.AsNoTracking().OrderBy(order).FirstOrDefault(@where);
            }
        }

        public IQueryable<T> Distinct(Expression<Func<T, bool>> @where)
        {
            return this._dbSet.AsNoTracking().Where(@where).Distinct();
        }

        public IQueryable<T> Where(Expression<Func<T, bool>> @where)
        {
            return this._dbSet.Where(@where);
        }

        public IQueryable<T> Where<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, bool isDesc = false)
        {
            if (isDesc)
            {
                return this._dbSet.Where(@where).OrderByDescending(order);
            }
            else
            {
                return this._dbSet.Where(@where).OrderBy(order);
            }
        }

        public IEnumerable<T> Where<TOrder>(Func<T, bool> @where, Func<T, TOrder> order, int pageIndex, int pageSize, out int count, bool isDesc = false)
        {
            count = Count();
            if (isDesc)
            {
                return this._dbSet.Where(@where).OrderByDescending(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
            else
            {
                return this._dbSet.Where(@where).OrderBy(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
        }

        public IQueryable<T> Where<TOrder>(Expression<Func<T, bool>> @where, Expression<Func<T, TOrder>> order, int pageIndex, int pageSize, out int count, bool isDesc = false)
        {
            count = Count();
            if (isDesc)
            {
                return this._dbSet.Where(@where).OrderByDescending(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
            else
            {
                return this._dbSet.Where(@where).OrderBy(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
        }

        public IQueryable<T> GetAll()
        {
            return this._dbSet.AsNoTracking();
        }

        public IQueryable<T> GetAll<TOrder>(Expression<Func<T, TOrder>> order, bool isDesc = false)
        {
            if (isDesc)
            {
                return this._dbSet.AsNoTracking().OrderByDescending(order);
            }
            else
            {
                return this._dbSet.AsNoTracking().OrderBy(order);
            }
        }

        public T GetById<Ttype>(Ttype id)
        {
            return this._dbSet.Find(id);
        }

        public Ttype Max<Ttype>(Expression<Func<T, Ttype>> column)
        {
            if (this._dbSet.AsNoTracking().Any())
            {
                return this._dbSet.AsNoTracking().Max<T, Ttype>(column);
            }
            return default(Ttype);
        }

        public Ttype Max<Ttype>(Expression<Func<T, Ttype>> column, Expression<Func<T, bool>> @where)
        {
            if (this._dbSet.AsNoTracking().Any(@where))
            {
                return this._dbSet.AsNoTracking().Where(@where).Max<T, Ttype>(column);
            }
            return default(Ttype);
        }

        public Ttype Min<Ttype>(Expression<Func<T, Ttype>> column)
        {
            if (this._dbSet.AsNoTracking().Any())
            {
                return this._dbSet.AsNoTracking().Min<T, Ttype>(column);
            }
            return default(Ttype);
        }

        public Ttype Min<Ttype>(Expression<Func<T, Ttype>> column, Expression<Func<T, bool>> @where)
        {
            if (this._dbSet.AsNoTracking().Any(@where))
            {
                return this._dbSet.AsNoTracking().Where(@where).Min<T, Ttype>(column);
            }
            return default(Ttype);
        }

        public TType Sum<TType>(Expression<Func<T, TType>> selector, Expression<Func<T, bool>> @where) where TType : new()
        {
            object result = 0;

            if (new TType().GetType() == typeof(decimal))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, decimal>>);
            }
            if (new TType().GetType() == typeof(decimal?))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, decimal?>>);
            }
            if (new TType().GetType() == typeof(double))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, double>>);
            }
            if (new TType().GetType() == typeof(double?))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, double?>>);
            }
            if (new TType().GetType() == typeof(float))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, float>>);
            }
            if (new TType().GetType() == typeof(float?))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, float?>>);
            }
            if (new TType().GetType() == typeof(int))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, int>>);
            }
            if (new TType().GetType() == typeof(int?))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, int?>>);
            }
            if (new TType().GetType() == typeof(long))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, long>>);
            }
            if (new TType().GetType() == typeof(long?))
            {
                result = this._dbSet.AsNoTracking().Where(where).Sum(selector as Expression<Func<T, long?>>);
            }
            return (TType)result;
        }

        public void Dispose()
        {
            this._dbContext.Dispose();
        }
    }
}
View Code

这样仓储模式就建立好了,接下来想办法经过DI建立实例,而不是直接在Service层new一个实例,可是Repository是泛型类,经过DI建立须要设置,全部不一样model类都要声明一遍,这里只能使用简单工厂来处理下。

添加RepositoryFactory类和IRepositoryFactory接口,接口中定义IRepository<T> CreateRepository<T>(IconcardContext mydbcontext) where T : class; 经过实现CreateRepository方法来建立不一样数据模型的工做单元。

IRepositoryFactory接口:

using System;
using System.Collections.Generic;
using System.Text;

namespace common.Interface
{
    public interface IRepositoryFactory
    {
        IRepository<T> CreateRepository<T>(IconcardContext mydbcontext) where T : class;
    }
}
View Code

RepositoryFactory类:

using common.Interface;
using System;
using System.Collections.Generic;
using System.Text;

namespace common.Core
{
    public class RepositoryFactory : IRepositoryFactory
    {
        public IRepository<T> CreateRepository<T>(IconcardContext mydbcontext) where T : class
        {
            return new Repository<T>(mydbcontext);
        }
    }
}
View Code

 

 第四步:建立Service层:

 老规矩,先添加新建项目Service和IService,一个是定义Service接口,另外一个是它的实现,他们都须要引入Model层和Interface层,Service要引入IService层。

添加BaseService类和IBaseService接口,接口中定义IRepository<T> CreateService<T>() where T : class, new();

IBaseService接口:

using common.Interface;
using System;
using System.Collections.Generic;
using System.Text;

namespace com.Synjones.IService
{
    public interface IBaseService
    {
        IRepository<T> CreateService<T>() where T : class, new();
    }
}
View Code

BaseService类:

using com.Synjones.IService;
using common.Interface;
using System;
using System.Collections.Generic;
using System.Text;

namespace com.Synjones.Service
{
    public class BaseService : IBaseService
    {
        private IRepositoryFactory _repositoryFactory;
        private IconcardContext _mydbcontext;
        public BaseService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext)
        {
            this._repositoryFactory = repositoryFactory;
            this._mydbcontext = mydbcontext;
        }

        public IRepository<T> CreateService<T>() where T : class, new()
        {
            return _repositoryFactory.CreateRepository<T>(_mydbcontext);
        }
    }
}
View Code

这里说明一下,BaseService类也是泛型类,也不须要经过DI方式建立,Service层中根据每一个模块添加一个Service类,而且继承BaseService类,DI依赖注入模块Service中直接获取到指定模型的仓储进行操做。

添加User模块UserService类和IUserService接口,UserService类继承父类BaseService,生成构造函数。

public UserService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext) : base(repositoryFactory, mydbcontext)
{
}

下面咱们简单举例对user表读取操做的业务层实现,定义接口List<User> GetUsers(),实现GetUsers()方法,读取全部user表数据。

IUserService接口:

using com.Synjones.Model.Models;
using System;
using System.Collections.Generic;
using System.Text;

namespace com.Synjones.IService
{
    public interface IUserService
    {
        List<User> GetUsers();
    }
}
View Code

UserService类:

using com.Synjones.IService;
using com.Synjones.Model.Models;
using common.Interface;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace com.Synjones.Service
{
    public class UserService : BaseService, IUserService
    {
        public UserService(IRepositoryFactory repositoryFactory, IconcardContext mydbcontext) : base(repositoryFactory, mydbcontext)
        {
        }

        public List<User> GetUsers()
        {
            var service = this.CreateService<User>();
            return service.GetAll().ToList();
        }
    }
}
View Code

 

 

第五步:UI建立并调用Service接口返回数据。

我这里建立了WebApi项目,依赖项中添加引用全部其余项目。

配置数据库链接字符串,打开appsettings.json,添加

"ConnectionStrings": {
    "SchoolConnection": "server=.;database=ConCard;uid=sa;pwd=123123;"
  }

配置EF服务注册:

打开Startup.cs,ConfigureServices方法中添加services.AddDbContext指定数据库链接配置项,经过services.AddScoped添加DI依赖注入配置。

public void ConfigureServices(IServiceCollection services)
{
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
      // 配置EF服务注册
      services.AddDbContext<common.Core.ConCardContext>(options =>
      options.UseSqlServer(Configuration.GetConnectionString("SchoolConnection")));
      services.AddScoped<IconcardContext, common.Core.ConCardContext>();
      services.AddScoped<IRepositoryFactory, RepositoryFactory>();
      services.AddScoped<IUserService, UserService>();
}

修改下ValuesController控制器,添加构造函数和Get方法。

WebApi项目设为启动项目,运行看结果。

 

相关文章
相关标签/搜索