Asp.Net DDDアーキテクチャの概要-領域区分、倉庫管理アプリケーション、サービス層定義

4994 ワード

このシリーズのディレクトリ


Asp.Net DDDアーキテクチャの簡単な説明--全体のフレームワークの説明Asp.Net DDDアーキテクチャの概要-領域区分、倉庫保管応用、サービス層定義Asp.Net DDDアーキテクチャの簡単な説明--画像のアップロード、サムネイルの剪断Asp.Net DDDアーキテクチャの概要-依存注入Autofac Asp.Net DDDアーキテクチャの概要-Webサイトの構成
ソフトウェア開発中のDDD、すなわち分野駆動設計、Domain-Driven Design.Googleの下で、多くの標準的な答えを説明することができます.私が理解しているのは、ビジネスを導くアーキテクチャ設計方式です.つまり、ビジネスロジックに基づいて分野を区分し、分野内の倉庫は自分で内部事務を管理し、分野間は倉庫インタフェースを通じてコミュニケーションし、テーブル間の外部キー関係を弱め、idだけでデータ関連を記録します.たとえば、ユーザーとロールの関係です.これは典型的な多対多の関係です.以前は関連テーブルで処理していました.
public class Users : AggregateRoot
{
        public Users()
        {
            UsersRoles = new HashSet();
        }

        [StringLength(50)]
        public string Realname { get; set; }

        [StringLength(50)]
        public string UserName { get; set; }

        //      ,         
        public virtual ICollection UsersRoles { get; set; }
}

public class UsersRoles: AggregateRoot
{
        public UsersRoles()
        {
            Users = new HashSet();
        }

        [Display(Name = "   ")]
        [Required(ErrorMessage = "   “{0}”")]
        [StringLength(50, ErrorMessage = "{0}  {1}   ")]
        public string Name { get; set; }
      
        //      ,         
        public virtual ICollection Users { get; set; }
}
このようなメリットは何ですか.EntityframeworkにはLazyLoadの特性があります.ユーザーを検索する必要がある場合は、関連するロールをロードする必要はありません.必要に応じてロードすればいいです.実際のプロジェクトでは、私が望んでいるデータの一部をロードすることはできません.このユーザーのすべてのロールをロードするか、ロードしません.DDDを経て、私は彼らを3つの独立した分野に分けました:Users、UsersRoles、User 2 Role
public class Users : AggregateRoot
{
        public Users()
        {
            UsersRoles = new HashSet();
        }

        [StringLength(50)]
        public string Realname { get; set; }

        [StringLength(50)]
        public string UserName { get; set; }
}

public class UsersRoles: AggregateRoot
{
        public UsersRoles()
        {
            Users = new HashSet();
        }

        [Display(Name = "   ")]
        [Required(ErrorMessage = "   “{0}”")]
        [StringLength(50, ErrorMessage = "{0}  {1}   ")]
        public string Name { get; set; }
      
}
[Table("User2Role")]
public class User2Role : AggregateRoot
{
        public long UserId
        {
            get;
            set;
        }

        public long RoleId
        {
            get;
            set;
        }

}
User 2 Roleクラスを通じてユーザーの役割をコミュニケーションし、ビジネスニーズに応じて問い合わせることができます.

集約ルート


上記の3つのクラスはAggregateRootを継承しています.これは集約ルート、すなわち最小ユニットの領域クラスです.定義を見てみましょう.
    public interface IAggregateRoot
    {
        long Id { get; set; }

        long CreateUserId { get; set; }
        string CreateUserName { get; set; }

        DateTime UpdateTime { get; set; }
    }
  • Idはプライマリ・キーです.
  • CreateUserIdとCreateUserNameは、作成者を記録するために作成されたものです.これは、データ権限の準備のためです.データ権限の後に関連する記事が表示されます.
  • UpdateTimeは更新時間であり、一般的にソートに用いられ、お客様が最近更新したデータが前に並ぶのが好きです.
  • データストア


    各分野のデータ倉庫を実現する時、いくつかの関数が同じであることを発見して、これらを抽出して、倉庫ベースクラスの中で実現します:
        public interface IRepository:IDisposable where T:class,IAggregateRoot
        {
            long Save(T obj, IDbTransaction trans = null);
            T Get(long id);
    
            long Insert(T obj, IDbTransaction trans = null);
    
            bool Delete(T obj, IDbTransaction trans = null);
    
            bool Update(T obj, IDbTransaction trans = null);
    
            string GetIP();
    
            int BatchDele(TableSource src, string ids, IDbTransaction trans = null);
            int BatchDele(TableSource src, IEnumerable idArra, IDbTransaction trans = null);
        }
    
    Repositoryのコードが多すぎて、貼らないで、みんなはソースコードを見に行くことができます.では、ユーザーの倉庫についてどのように書くか、まず倉庫インタフェースを定義します.
        public interface IUsersRepository:IRepository
        {
            Users GetByGid(string gid);
        }
    
    次に、実装クラスがRepositoryを同時に継承するには、次の手順に従います.
        public class UsersRepository : Repository, IUsersRepository
        {
            public ICacheManager Cache { get; set; }
            public Users GetByGid(string gid)
            {
                if (string.IsNullOrEmpty(gid))
                {
                    return null;
                }
                var arr = gid.Split('-');
                if (arr.Length < 2)
                {
                    return null;
                }
                var id = StringUtility.ConvertToBigInt(arr[1]);
                if (id == 0)
                {
                    return null;
                }
                return Get(id);
            }
      }
    

    Servicesレイヤ


    実際のプロジェクトでは、ビジネスロジックは複雑で、多分野に関連していることが多いことがわかります.そのため、Servicesレベルの定義が1つ増えました.Steven.Domain.Servicesは、ユーザーとロールの例を示します.
  • いくつかのビジネスロジックの下で、ユーザーデータを手に入れるだけでいいので、IUserRepositoryを使えばいいです.
  • 他のいくつかのロジックの下で、いくつかのロールのすべてのユーザーを取得し、ビジネスロジックはすでにユーザーとロールに関連しており、そのうちの1つの倉庫に単独で置くのは明らかによくありません.この場合、IUserRoleSvcを使用することができます.