一文で読めるNetcore依存注入(Dependency injection)

8669 ワード

一文で読めるNetcore依存注入(Dependency injection)


一、依存注入とは何か

  • は、まずAsp.Netcoreでは依存注入をサポートするソフトウェア設計モード、あるいは依存注入はaspである.Netcoreのコア;
  • 依存注入(DI)と制御反転(IOC)は基本的に同じ意味で、誰もが誰から離れられないからだ.あるいは彼らは同じ概念の異なる角度で説明していると言える.
  • ソフトウェア設計原則には、デカップリングのための依存逆置原則(DIP)がある.上位モジュールは下位モジュールに依存するべきではありません.どちらも抽象に依存しなければならない.抽象は細部に依存すべきではなく、細部は抽象に依存すべきである.依存注入はこのような原則を実現する方法の一つである.
  • 現実の例を挙げると、明ちゃんは行政に行って5番の電池を受け取って、それから行政は明ちゃんに黒い象札の5番の電池をあげて分析しました.
  • 小明は行政に5番の電池を受け取るだけでいいです.小明はブランドの電池、電池がどこから来たのか、電池の価格などに関心を持つ必要はありません.彼ら二人が共通に関心を持っているのは5番の電池でいいです.
  • 後期行政が小明北孚電池を与えたとしても、小明は正常に使用することができる.彼らは1つのルール(5番電池)を満たすだけでいいです.
  • 小明(高層モジュール)はブラックチップ電池(低層モジュール)に依存すべきではなく、どちらも5番電池(抽象)に依存すべきである.
  • 明が直接(new)ブラックチップ電池を手に入れた場合、後期の業務変更が北孚電池を提供している場合は、明のコードを変更する必要があります.また、会社に数百人の明ちゃんがいれば、コードの量は考えられます.
  • 直接取得(new)ブラックチップ電池を解決するために、簡単に言えば結合を理解するために、私たちは従業員一人一人に行政を通じて(関数、属性、方法などを構築する)を受け取り、このような他のブランドを変更しても、明ちゃんは関心を持つ必要はありません.
  • 個挙げます.Net coreの例:.Net coreでは分散キャッシュが使用されます.
  • コンストラクション関数でIDistributedCacheを取得するだけで、メソッドでキャッシュを直接使用することができます.キャッシュの実装方法、ストレージの場所などに関心を持つ必要はありません.
  • キャッシュがメモリからRedisまたはsqlserverに変更され、自分でキャッシュを実装する場合でも、コンフィギュレーション・サービスでキャッシュを使用する場所を変更することなく、特定の実装方法を変更する必要があります.
  •  


    二、Asp.Netcoreにおける依存注入のライフサイクル


    注入に依存するライフサイクルには3つのTransient,Scoped,Singletonがある.
    1、Transientは呼び出しのたびに異なる例である、例えばよく使われるMicrosoft.Extensions.Options.IConfigureOptions;
    2、Scopedは要求ごとに同じインスタンスであり、例えばEntity Framework contextsである.
    3、SingletonはMicrosoftのような一例しかない.Extensions.Logging.ILogger;
    具体的にどの種類を使うかは、具体的な状況によって決まる.
    1、例えば、私たちの一般的なビジネスロジックはTransientで、これもよく使われています.
    2、Scopedは相対的に少ないので、もちろん多くの業務ロジックもScopedを使うことができます.もちろん、彼の妙用は、システム内でログインシステムユーザーのIdを取得するなど、インスタンスを要求するたびにScopedを使用することができます.この場合、サービス層やRepository層などにかかわらず、同じユーザーを取得することができます. 
    3、Singletonの多くはシステムレベルの設計用単利で、例えばログである.
     

    三、Asp.Netcoreでの依存注入の使用


    基本ビジネスロジックコード、ユーザーリストの取得
    public interface IUserInfoService
        {
            IEnumerable GetUserInfo();
        } 
        public class UserInfoService : IUserInfoService
        {
            public IEnumerable GetUserInfo()
            {
                //   db    
                return new List { new UserInfo { Id = 1, Name = "Emrys" }, new UserInfo { Id = 2, Name = "  " } };
            }
        } 
        public class UserInfoMongoService : IUserInfoService
        {
            public IEnumerable GetUserInfo()
            {
                //   Mongodb    
                return new List { new UserInfo { Id = 1, Name = "Emrys" }, new UserInfo { Id = 2, Name = "  " } };
            }
        } 
        public class UserInfo
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
     

    1、伝統方式

     public class ValuesController : ControllerBase
        {
            IUserInfoService _userInfoService = new UserInfoService();
             
            [HttpGet]
            public IEnumerable Get()
            { 
                return _userInfoService.GetUserInfo();
            }
    
        }
    伝統的な方法の中で、ユーザーのサービス類を取得して直接newの方式を使って、これも多くの初心者あるいは多くのベテランが最もよく使う方式です;コード結合度が高すぎてメンテナンスに非常に不利であり、IUserInfoServiceに使用されるすべての場所でnewがオブジェクトから出ることがわかります.
    後で変更が必要な場合は、Mongodbからデータを取得するなど、IUserInfoServiceの実装を置き換える必要があります(実際の例では、ブラックボードからノースモービルバッテリに変更されます).では、すべてのnewでUserInfoServiceを出た場所でコードを変更してUserInfoMongoService、IUserInfoService_userInfoService = new UserInfoMongoService();
    我々がnewを必要とするオブジェクトが単一のモード(Singleton)を実装する必要があり、newに1つのオブジェクト(Scoped)モードを要求するたびに、コード実装を別途書く必要がある.
     

    2、依存注入方式


    1、StartupクラスのConfigureServicesメソッドに注入を設定する

    public void ConfigureServices(IServiceCollection services)
    { 
        services.AddTransient(); 
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    2、コンストラクション関数でインスタンスを取得する

    public class ValuesController : ControllerBase
    {
        IUserInfoService _userInfoService; 
        public ValuesController(IUserInfoService userInfoService)
        {
            _userInfoService = userInfoService;
        }
    
        [HttpGet]
        public IEnumerable Get()
        { 
            return _userInfoService.GetUserInfo();
        }
    
    }
    依存注入方式を用いる場合、従来方式の結合度は解決され、後で変更が実現される場合、services.AddTransientUserInfoService>();UserInfoMongoServiceに変更すればいいです.
    IUserInfoServiceを使用するすべての場所で変更する必要はありません.ライフサイクル(Transient,Scoped,Singleton)を非常に簡単に設定できます.
     

    四、まとめ


    1、注入を設定して取得する方法は一つだけではなく、例は最も簡単で最もよく使われる使用方法を示しただけで、他の方法はドキュメントを参照することができる.
    2、取り替えることができる.Netcoreのデフォルトの注入容器、例えばよく使われるautofacは、より強力な機能を実現することができます.詳細はこちらhttps://autofac.org/;その他の容器は参考にできますhttps://github.com/aspnet/Extensions/tree/master/src/DependencyInjection
    3、注入@inject IUserInfoService userInfoServiceをViewで直接入手できる
    4、httpcontextで注入HttpContextを直接取得できる.RequestServices.GetService();
    5、Startupの中のConfigureServicesの方法は注入を設定するために存在する.
     
    お勧めを覚えています^^;