記録:ASPの使い方NET CoreとEnityFramework Coreは、データベース操作とデータベースエンティティのプロジェクト分離を実現します.

3265 ワード

前情提要:
既存のウェブサイトフレームワークは、マスタープロジェクトWebApp、IidentityUserインタフェースを含むベースプロジェクトAを含む.ユーザ認証を処理するためのサービスAuthenticationServiceはネーミングスペースBにある.データを保存するエンティティUser:IidentityUserロケーション項目C.プロジェクト間の関係はBとC依存プロジェクトAである.
 
必要:
新しいプロジェクトDがあります.このプロジェクトにはDUser:IidentityUserがあります.どのように処理すれば最も優雅に参照を追加したり修正したりしないで、ユーザーをDUserに保存することができます.
 
実際の例:
ASP.NET COREには、IdentityServerというものがあります.中にはIdentityServerBuilderのようなものが入っていますAddService()というコードは、どのように実現されますか?
 
ソリューション:
1、新しい汎用クラスを作成します(このクラスはinternalとマークできます.外部は理解する必要はありません.アクセスする必要もありません):
public class UserContext
        where TUser : class, IIdentityUser, new ()
    {
        public YourContext dbContext;
        public UserContext(YourContext ctx) => dbContext = ctx;

        public DbSet Users
        {
            get
            {
                return dbContext.Set();
            }
        }

        public void SaveChanges()
        {
            dbContext.SaveChanges();
        }
    }

2、操作用のサービスを新設する(注意、必要な操作はすべてこの中に書いて、将来暴露するのもこのインタフェース)
public class UserService : IUserService
        where TUser: class, IIdentityUser, new()
    {
        private UserContext dbContext;
        public UserService(YourContext ctx, IServiceProvider provider)
        {
            dbContext = new PermissionContext(ctx.DbContext);
        }
     
   public TUser GetUserById(Guid id)
   {
      return dbContext.Users.FirstOrDefault(e => e.ID == id);
   }
    }

  
3、注射器を追加する
    public static class AuthenticationInject
    {
        public static IServiceCollection AddAuthenticationContext(this IServiceCollection services)
            where TUser: IIdentityUser
        {
            var serviceType = typeof(UserService<>).MakeGenericType(typeof(TUser));
            services.AddSingleton(typeof(IUserService), serviceType );

            return services;
        }
    }

技術点:MakeGenericTypeメソッドを使用すると、汎用クラスインスタンスを動的にロードできます.タイプがUserServiceの場合はtypeof(UserService)と書く.MakeGenericType(typeof(T1), typeof(T2))
これで,汎クラスのタイプ名を変数に分解した.そして1万種類の模様を遊ぶことができます.
4、WebAppに相関変数を注入する
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthenticationContext();
        }

  
依存関係の解析:
実行項目WebApp依存A,B,D,B,D項目はAのみ依存する.さらに、ここではさらにデカップリングすることもできます.関数AddAuthenticationContextを汎用関数からAddAuthenticationContext(Type userType)に変更し、さらにAddAuthenticationContext(string type)に変更し、反射と構成によってタイプを取り、AプロジェクトとDプロジェクトをデカップリングすることもできます.
拡張性:
将来的には、新しいプロジェクトE、EUserがあります.DとAを分離解除してEとAを関連付けるだけです.AddAuthenticationContext関数を変更するだけで、要件を満たすことができます.もちろん、気持ちがあれば、自動的に発見されるコードを作ることもできます(例えば、私のプロジェクトではそうしています.IidentityUserのオブジェクトを自動的に分析し、Contextに添付します.複数の実装時に正しく追加できるように、このプロジェクトでどのUserを使用するかをマークするためにAttributeを作りました).また気持ちがあれば配置式にすることもできますが、どうせEF Coreを1万種類のポーズにすることができます.