Asp.Net Core 2.0の旅---AutoFac倉庫の汎用的な依存注入

6942 ワード

前節のブログでAutoFac IOCコンテナの使用チュートリアルの最後に、次の節では倉庫の汎用的な依存注入について詳しく説明します.今回の記事では詳細な例を示します.
1、なぜ倉庫の汎用注入が必要なのか.
まずコードを入れます.
 public class ShareYunSourseAppService :IShareYunSourseAppService
    {
        private readonly IRepository _yunsourseIRepository;
        public ShareYunSourseAppService(IRepository yunsourseIRepository)
        {
            _yunsourseIRepository = yunsourseIRepository;
        }
        public async Task GetName()
        {
            var list = _yunsourseIRepository.GetAll().Where(m=>!string.IsNullOrEmpty(m.Content)).ToList();

        }
    }

上のコードから,エンティティ倉庫への依存注入がどれほど簡潔であるかが分かる.エンティティの倉庫を取得するために倉庫インタフェースを新規作成し、その実現クラスを新規作成し、倉庫ベースクラスを継承する人がいると信じています.1つのエンティティもまあまあですが、10、100個なら、その中の重複作業は特に大きいのではないでしょうか.デルの開発者の生産性を向上させるために.この文章は育まれて生まれた.ここでは、倉庫の汎用的な依存注入を実現する方法を一歩一歩紹介します.
2、倉庫インタフェースIrepositoryの定義
   /// 
    ///       
    /// 
    /// 
    public interface IRepository where T : Entity
    {
        /// 
        /// IQueryable to be used to select entities from database
        /// 
        /// 
        IQueryable GetAll();
        /// 
        ///         
        /// 
        ///      List  
        List GetAllList();
        /// 
        ///          
        /// 
        ///      List  
        Task> GetAllListAsync();
        /// 
        ///                
        /// 
        ///      List  
        /// 
        List GetAllList(Expression> predicate);

        /// 
        ///     ,  id    
        /// 
        /// 
        /// 
        T GetById(object id);

        /// 
        ///     --    
        /// 
        /// 
        void Insert(T model);

        /// 
        ///     ,    
        /// 
        /// 
        void Update(T model);

        /// 
        ///     --    
        /// 
        /// 
        void Delete(T model);

        /// 
        ///   Table
        /// 
        IQueryable Table { get; }
    }

倉庫インタフェースIrepositoryの汎用タイプはEntityタイプでなければなりません.
   /// 
    ///       
    /// 
    ///     
    public abstract class Entity
    {
        /// 
        ///   
        /// 
        public virtual TPrimaryKey Id { get; set; }
    }

    /// 
    ///          int     
    /// 
    public abstract class Entity : Entity
    {

    }

2、その倉庫インタフェースを実現する
  /// 
    ///      ,        。
    /// 
    /// 
    public class EfRepositoryBase : IRepository where T : Entity  //      。
    {
        private readonly YunSourseMySqlContext _context;
        private DbSet _entities;

        /// 
        /// 
        /// 
        public EfRepositoryBase(YunSourseMySqlContext context)
        {
           _context = context;
        }

        public IQueryable GetAll()
        {
            return Table;
        }
        public  List GetAllList()
        {
            return  GetAll().ToList();
        }
        public  List GetAllList(Expression> predicate)
        {
            return  GetAll().Where(predicate).ToList();
        }
        public  async Task> GetAllListAsync()
        {
            return await GetAll().ToListAsync();
        }

        public  async Task> GetAllListAsync(Expression> predicate)
        {
            return await GetAll().Where(predicate).ToListAsync();
        }
        public DbSet Entities
        {
            get
            {
                if (_entities == null)
                {
                    _entities = _context.Set();
                }
                return _entities;
            }
        }

        /// 
        ///         IQueryable    Table  
        ///    virtual        
        /// 
        public virtual IQueryable Table
        {
            get
            {
                return this.Entities;
            }

        }

        public T GetById(object id)
        {
            return this.Entities.Find(id);
        }

        public void Insert(T model)
        {
            try
            {
                if (model == null)
                {
                    throw new ArgumentNullException("model");
                }
                else
                {
                    this.Entities.Add(model);
                    this._context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public void Update(T model)
        {
            try
            {
                //model  ,    
                if (model == null)
                {
                    throw new ArgumentNullException("model");
                }
                else
                {
                    //     
                    this._context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public void Delete(T model)
        {
            try
            {
                if (model == null)
                {
                    throw new ArgumentNullException("entity");
                }
                this.Entities.Remove(model);
                this._context.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
    }

EfRepositoryBaseはIrepositoryの実装であり、その汎用タイプもEntityタイプである.
3、倉庫インタフェースと倉庫実現クラスが完成した後、倉庫の汎用的な依存注入を行う必要がある.
WebプロジェクトのStatrup起動クラスでのConfigureServicesメソッド
   builder.RegisterGeneric(typeof(EfRepositoryBase<>)).As(typeof(IRepository<>)).InstancePerDependency();//      
InstancePerDependency//呼び出すたびにオブジェクトが再インスタンス化されます.リクエストのたびに新しいオブジェクトが作成されます.
4、これでおめでとうございます.倉庫汎用型の依存注入を完了したら、冒頭で示した構造方法による依存注入の方法で倉庫汎用型をインスタンス化することができます.定義されたエンティティはEntityを継承する必要があります.
5、不足点:事務が展示されていない.今後の勉強で発表されるかもしれません.
保存方法ABPフレームワークの一部を汲み取った方法です.自分で広げることができます.次回シェアするのはMiniProfilerで、興味のある仲間は自分で検索することができます.
討論を歓迎して、共に勉強します.........