• DDD领域驱动之干货(三)完结篇!


    首先这里发一下结构图,因为是重写的,但是代码都是一样所有如下:

    这里我先说一下看了大部分的DDD文章都是采用的WCF做服务,这里呢我用的是webapi做服务,WCF和WEBAPI的区别可以去百度下。

    好了。现在我们看下automapper的具体实现。

    因为automapper又一个Profile类,而我们自己写的类去继承这个类,所有如下图:

    上图是创建映射关系,下面就去添加映射

    这些做完了 我们现在需要使用

    这里的dto类型是CostomDTO 也就是数据传输对象。

    下面我们来看下工作单元,下面我直接贴代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.Repository.UnitOfWork
    {
        /// <summary>
        /// 表示所有集成该接口都是工作单元的一种实现
        /// </summary>
        public interface IUnitOfWork
        {
            /// <summary>
            /// 提交
            /// </summary>
            void Commit();
    
            /// <summary>
            /// 异步提交
            /// </summary>
            /// <returns></returns>
            Task CommitSyncAsync();
    
            /// <summary>
            /// 回滚
            /// </summary>
            void Rollback();
    
            /// <summary>
            /// 已经提交过了
            /// </summary>
            bool Committed { get; }
    
            /// <summary>
            /// 事务支持
            /// </summary>
            //bool DistributedTransactionSupported { get; }
        }
    }
    View Code

    这是IUnitOfWork接口代码。

    using KuRuMi.Mio.DoMainModel.BaseModel;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.Repository.UnitOfWork
    {
        public interface IUnitOfWorkContext : IUnitOfWork, IDisposable
        {
            /// <summary>
            /// 将指定的聚合根标注为“新建”状态。
            /// </summary>
            /// <typeparam name="TAggregateRoot">需要标注状态的聚合根类型。</typeparam>
            /// <param name="obj">需要标注状态的聚合根。</param>
            void RegisterNew<TAggregateRoot>(TAggregateRoot obj)
                where TAggregateRoot : class, IAggregateRoot;
            /// <summary>
            /// 将指定的聚合根标注为“更改”状态。
            /// </summary>
            /// <typeparam name="TAggregateRoot">需要标注状态的聚合根类型。</typeparam>
            /// <param name="obj">需要标注状态的聚合根。</param>
            void RegisterModified<TAggregateRoot>(TAggregateRoot obj)
                where TAggregateRoot : class, IAggregateRoot;
            /// <summary>
            /// 将指定的聚合根标注为“删除”状态。
            /// </summary>
            /// <typeparam name="TAggregateRoot">需要标注状态的聚合根类型。</typeparam>
            /// <param name="obj">需要标注状态的聚合根。</param>
            void RegisterDeleted<TAggregateRoot>(TAggregateRoot obj)
                where TAggregateRoot : class, IAggregateRoot;
        }
    }
    View Code

    这是IUnitOfWorkContext接口代码

    因为我是基于EF实现的所以这里多了一层EF的工作单元代码

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.Repository.UnitOfWork
    {
        /// <summary>
        /// 表示是EF仓储的一种实现
        /// </summary>
        public interface IEFUnitOfWorkContext : IUnitOfWorkContext
        {
            DbContext Context { get; }
        }
    }
    View Code

    完成这里接下来就是工作单元的实现类

    using KuRuMi.Mio.DoMainModel.BaseModel;
    using KuRuMi.Mio.DoMain.Infrastructure;
    using KuRuMi.Mio.DoMain.Repository.EFRepository;
    using KuRuMi.Mio.DoMain.Repository.UnitOfWork;
    using System.Data.Entity;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.Repository.BaseUnitOfWork
    {
        public class UnitOfWorkContext: DisposableObject, IEFUnitOfWorkContext
        {
            private KurumiMioDbContext kurumi = null;
    
            public UnitOfWorkContext() {
                kurumi = new KurumiMioDbContext();
            }
    
            public DbContext Context { get { return kurumi; } }
    
            #region 工作单元
            public bool Committed { get; protected set; }
    
            /// <summary>
            /// 同步提交
            /// </summary>
            public void Commit()
            {
                if (!Committed)
                {
                    //kurumi.Value.GetValidationErrors();
                    Context.SaveChanges();
                    Committed = true;
                }
            }
    
            /// <summary>
            /// 异步提交
            /// </summary>
            /// <returns></returns>
            public async Task CommitSyncAsync()
            {
                if (!Committed)
                {
                    await Context.SaveChangesAsync();
                    Committed = true;
                }
            }
            /// <summary>
            /// 释放资源
            /// </summary>
            /// <param name="disposing"></param>
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    if (!Committed)
                        Commit();
                    Context.Dispose();
                    kurumi.Dispose();
                }
            }
    
            /// <summary>
            /// 回滚
            /// </summary>
            public void Rollback()
            {
                Committed = false;
            }
            #endregion
    
            #region IEFUnitOfWorkContext接口
            /// <summary>
            /// 删除未提交
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="obj"></param>
            public void RegisterDeleted<TAggregateRoot>(TAggregateRoot obj) where TAggregateRoot : class, IAggregateRoot
            {
                Context.Entry(obj).State = EntityState.Deleted;
                Committed = false;
            }
    
            /// <summary>
            /// 修改未提交
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="obj"></param>
            public void RegisterModified<TAggregateRoot>(TAggregateRoot obj) where TAggregateRoot : class, IAggregateRoot
            {
                if (Context.Entry(obj).State == EntityState.Detached)
                {
                    Context.Set<TAggregateRoot>().Attach(obj);
                }
                Context.Entry(obj).State = EntityState.Modified;
                Committed = false;
            }
    
            /// <summary>
            /// 新建未提交
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="obj"></param>
            public void RegisterNew<TAggregateRoot>(TAggregateRoot obj) where TAggregateRoot : class, IAggregateRoot
            {
                var state = Context.Entry(obj).State;
                if (state == EntityState.Detached)
                {
                    Context.Entry(obj).State = EntityState.Added;
                }
                Committed = false;
            }
            #endregion
        }
    }
    View Code

    现在呢就是我的仓储,因为是聚合根的缘故,所以聚合后的根有自己特有的仓储代码如下。

    using KuRuMi.Mio.DoMainModel.Model;
    using KuRuMi.Mio.DoMainModel.Repositories;
    using KuRuMi.Mio.DoMain.Repository.EFRepository;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.Repository.ModelRepository
    {
        public class CostomRepositoryImpl :RepositoryImpl<Costom>, ICostomRepository
        {
            public KurumiMioDbContext context => lazy.Context as KurumiMioDbContext;
            public Costom GetAll()
            {
                string sql = "select * from Costom";
                return context.costom.SqlQuery(sql).FirstOrDefault();
            }
        }
    }
    View Code

    然后是我的总仓储的实现

    using KuRuMi.Mio.DoMainModel.BaseModel;
    using KuRuMi.Mio.DoMainModel.Repositories;
    using KuRuMi.Mio.DoMain.Repository.BaseUnitOfWork;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.Repository.EFRepository
    {
        /// <summary>
        /// 仓储的泛型实现
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        public class RepositoryImpl<TEntity> : IRepository<TEntity> where TEntity : AggregateRoot
        {
            public readonly UnitOfWorkContext lazy = null;
            public RepositoryImpl()
            {
                lazy = new UnitOfWorkContext();
    
            }
    
            /// <summary>
            /// 新增
            /// </summary>
            /// <param name="aggregateRoot"></param>
            public virtual void Add(TEntity aggregateRoot)
            {
                lazy.RegisterNew<TEntity>(aggregateRoot);
                lazy.Commit();
            }
            /// <summary>
            /// 通过key获取聚合根
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public virtual TEntity GetKey(Guid key)
            {
                return lazy.Context.Set<TEntity>().Find(key);
            }
    
            public virtual IQueryable<TEntity> LoadAll(Expression<Func<TEntity, bool>> predicate)
            {
                return lazy.Context.Set<TEntity>().Where(predicate).AsQueryable();
            }
            /// <summary>
            /// 复杂查询
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public virtual IQueryable<TEntity> LoadForSql(string sql)
            {
                return lazy.Context.Set<TEntity>().SqlQuery(sql).AsQueryable();
            }
    
            public virtual IEnumerable<TEntity> LoadListAll(Expression<Func<TEntity, bool>> predicate)
            {
                return lazy.Context.Set<TEntity>().Where(predicate).ToList();
            }
            /// <summary>
            /// 复杂查询
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public virtual IEnumerable<TEntity> LoadListForSql(string sql)
            {
                return lazy.Context.Set<TEntity>().SqlQuery(sql).ToList();
            }
    
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="aggregateRoot"></param>
            public virtual void Remove(TEntity aggregateRoot)
            {
                lazy.RegisterDeleted<TEntity>(aggregateRoot);
                lazy.Commit();
            }
    
            /// <summary>
            /// 修改
            /// </summary>
            /// <param name="aggregateRoot"></param>
            public virtual void Update(TEntity aggregateRoot)
            {
                lazy.RegisterModified<TEntity>(aggregateRoot);
                lazy.Commit();
            }
        }
    }
    View Code

    现在回到我们的服务层

    系统初始化我采用的是autofac,至于为什么不采用unity,博主个人喜欢用autofac原因轻量,简单。

    好了下面献上我的初始化系统类。

    using KuRuMi.Mio.DataObject.AutoMapperDTO;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using KuRuMi.Mio.DoMain.Infrastructure.IocManager;
    using KuRuMi.Mio.DoMainModel.Repositories;
    using Autofac;
    
    namespace KuRuMi.Mio.BootStarp
    {
    
        /// <summary>
        /// 系统初始化
        /// </summary>
        public class OptionBootStarp
        {
            protected IEnumerable<Assembly> assembles { get; }
            protected IIocManager ioc { get; }
            public OptionBootStarp(IEnumerable<Assembly> ass)
            {
                assembles = ass;
                ioc = IocManager.Instance;
            }
            protected IEnumerable<Type> Repository => assembles.SelectMany(a => a.ExportedTypes.Where(t => t.GetInterfaces().Contains(typeof(IBaseRepository))));
            protected IEnumerable<Type> BaseDTO => assembles.SelectMany(a => a.ExportedTypes.Where(t => t.GetInterfaces().Contains(typeof(IAutoMapper))));
    
            protected IEnumerable<Type> Services => assembles.SelectMany(a => a.ExportedTypes.Where(t => t.GetInterfaces().Contains(typeof(IService))));
            /// <summary>
            /// 预加载
            /// </summary>
            public void Initialize()
            {
                //加载所有DTO
                BaseDTO.ToList().ForEach(s=> {
                    var dtpye= Activator.CreateInstance(s) as IAutoMapper;
                    ioc.build.RegisterInstance(dtpye).As<MapperConfigurationImpl>().SingleInstance().PropertiesAutowired();
                });
                //加载所有的仓储
                Repository.ToList().ForEach(s => {
                    if (s.IsClass == true && s.IsGenericType == false)
                    {
                        var dtpye = Activator.CreateInstance(s);
                        ioc.build.RegisterType(dtpye.GetType()).As(dtpye.GetType());
                    }
                });
                //加载所有服务
                Services.ToList().ForEach(s =>
                {
                    if (s.IsClass == true)
                    {
                        var stype = Activator.CreateInstance(s);
                        ioc.build.RegisterType(stype.GetType()).As(stype.GetType());
                    }
                });
                PostInit();
            }
            /// <summary>
            /// 注入
            /// </summary>
            protected void PostInit() {
                ioc.CompleteBuild();
            }
        }
    
    }
    View Code

    下面贴上测试结果,WEB端请求的是webapi其中涉及到跨域请求问题,采用的是微软的cors包。

    需要代码的同学点这里。

    PS:采用了autofac IOC框架 automapper 映射框架 Log4Net 日志 ORM是EF 用的是codefirst 运行的时候只需要改web.config的数据库连接就可以了。

    链接: 百度 密码: 3baw

  • 相关阅读:
    git 删除已经提交的文件
    IDEA不显示service 服务窗口
    MySQL SQL语句查询结果 多列合并为1列
    Linux远程执行脚本
    mycat 连接命令
    win10 关闭被占用的端口
    ERROR 1045 (HY000): Access denied for user 'root', because password is error
    unblock with 'mysqladmin flush-hosts'
    neo4j数据库cypher查询
    基于websocket的网页实时消息推送与在线聊天(上篇)
  • 原文地址:https://www.cnblogs.com/edna-lzh/p/6912439.html
Copyright © 2020-2023  润新知