中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

DotNetCore跨平臺~一起聊聊Microsoft.Extensions.DependencyInjection

回到目錄

寫這篇(pian)文(wen)章的心情:激動

Microsoft.Extensions.DependencyInjection在(zai)(zai)(zai)github上同(tong)樣是(shi)開(kai)源的(de)(de),它在(zai)(zai)(zai)dotnetcore里(li)被廣泛的(de)(de)使(shi)用,比起(qi)(qi)之前的(de)(de)autofac,unity來說(shuo),它可以(yi)說(shuo)是(shi)個包裹,或者叫適配器,它自己提供了默(mo)認的(de)(de)DI實現(xian),同(tong)時也(ye)(ye)支持第三方的(de)(de)IOC容器,在(zai)(zai)(zai)這(zhe)段時間里(li)使(shi)用了它,就想(xiang),這(zhe)東西為什(shen)么被在(zai)(zai)(zai)dotnetcore里(li)大放異彩?為什(shen)么會全程(cheng)使(shi)用它?從(cong)程(cheng)序的(de)(de)開(kai)始到程(cheng)序啟動(dong)起(qi)(qi)來,你可以(yi)發(fa)現(xian)它無處不在(zai)(zai)(zai),在(zai)(zai)(zai)框架里(li)是(shi)這(zhe)樣,在(zai)(zai)(zai)業務層(ceng)同(tong)時也(ye)(ye)是(shi)這(zhe)樣。

聊聊Microsoft.Extensions.DependencyInjection知識點包括

  1. 它的開源地址
  2. IServiceCollection和IApplicationBuilder
  3. 自定義模塊用它
  4. 在Startup.ConfigureServices中注冊自定義模塊
  5. 在Startup.Configure中使用它,進行默認模塊的初始化
  6. 在任意對象的構造方法中使用它

一步一步的揭秘

一(yi) 它的開源(yuan)地(di)址

可以看(kan)看(kan)它(ta)的README.md,就(jiu)知道它(ta)是(shi)個大包裹(guo),類(lei)似于(yu)大叔LindAgile里的Container,完全可以擴展支持其它(ta)第三(san)方的IOC容器,這就(jiu)像大叔經常(chang)說的那(nei)句話一樣(yang),在IT江湖中,英雄(xiong)總是(shi)所風略(lve)同……

二 dotnetcore整(zheng)個(ge)框架在用它(ta)

在你(ni)的(de)dotnetcore應用程(cheng)序(xu)里,你(ni)會發現在Startup類中有很多像services.AddMvc()這(zhe)樣的(de)方法,這(zhe)實質是像應用程(cheng)序(xu)中注冊一個組件(jian)(jian),這(zhe)里的(de)MVC是一個統一的(de)組件(jian)(jian),它(ta)不(bu)依賴(lai)于windows,不(bu)依賴(lai)于dotnet,整(zheng)個dotnetcore里把很多組件(jian)(jian)都解耦了,這(zhe)樣在維護(hu)和nuget包(bao)升級(ji)時都更靈活,自己(ji)有問題就優化自己(ji),而不(bu)影響(xiang)其它(ta)模塊。(越說越像微服務的(de)宗旨)。

IServiceCollection主要用(yong)來(lai)注(zhu)冊(ce)服(fu)務(wu),就是(shi)某(mou)個接口(kou)和某(mou)種實現的(de)對(dui)應關系,這種注(zhu)冊(ce)是(shi)我們在(zai)Startup.ConfigureServices方法(fa)里完成的(de),如下(xia)面的(de)AddLind()這個方法(fa),它(ta)完成了對(dui)Lind模(mo)塊的(de)注(zhu)冊(ce),在(zai)方法(fa)內部(bu)可以注(zhu)冊(ce)本模(mo)塊的(de)其它(ta)服(fu)務(wu)。

        /// <summary>
        /// 添加Lind框架(jia)和它(ta)們依賴子模塊
        /// </summary>
        /// <param name="services"></param>
        /// <param name="setupAction"></param>
        /// <returns></returns>
        public static LindBuilder AddLind(
            this IServiceCollection services,
            Action<LindOptions> setupAction)
        {
            if (setupAction == null) throw new ArgumentNullException(nameof(setupAction));
            services.Configure(setupAction);
            var options = new LindOptions();
            //注(zhu)冊框架所依賴的(de)基礎(chu)模塊(kuai)
            //options.Extensions.Add();
            //注冊外部模(mo)塊
            setupAction(options);
            foreach (var serviceExtension in options.Extensions)
                serviceExtension.AddServices(services);
            services.AddSingleton(options);
            return new LindBuilder(services);
        }

IApplicationBuilder是指對應該程序的(de)啟(qi)動,或者理(li)解為初(chu)始化(hua),當上面(mian)的(de)服(fu)務注冊完(wan)成后就執(zhi)行它了,我們一般在Startup.Configure去激活它,它的(de)目的(de)比(bi)較單純,就是對模塊進行初(chu)始化(hua),如果(guo)沒什么(me)特殊的(de)功能,這(zhe)個代碼可以是空的(de),下(xia)面(mian)Builder中(zhong)初(chu)始化(hua)了日(ri)志組件。

        /// <summary>
        /// 在應用程序中(zhong)開啟-Lind框架
        /// </summary>
        /// <param name="app">The <see cref="IApplicationBuilder" /> instance this method extends.</param>
        /// <returns>The <see cref="IApplicationBuilder" /> instance this method extends.</returns>
        public static IApplicationBuilder UseLind(this IApplicationBuilder app)
        {
            if (app == null)
                throw new ArgumentNullException(nameof(app));
            var provider = app.ApplicationServices;

            //注冊Lind框架所需要的底層服務
            LoggerFactory.SetLogger((ILogger)provider.GetService(typeof(ILogger)));
            return app;
        }

三 自定義模塊用它

如(ru)果(guo)希望(wang)定(ding)義自(zi)己的(de)(de)功能模(mo)塊(kuai)實(shi)現與dotnetcore框(kuang)架的(de)(de)結合可以自(zi)定(ding)義Options和OptionsExtensions,前(qian)者主(zhu)要(yao)實(shi)現的(de)(de)是(shi)服務列表的(de)(de)注(zhu)(zhu)冊(ce),而后臺(tai)主(zhu)要(yao)是(shi)對現有(you)模(mo)塊(kuai)提供注(zhu)(zhu)冊(ce)的(de)(de)入(ru)口(kou),下(xia)面的(de)(de)代(dai)碼主(zhu)要(yao)實(shi)現了一個(ge)EF倉儲模(mo)塊(kuai)的(de)(de)注(zhu)(zhu)冊(ce)過程。

模塊所需的模型

    public class RepositoryOptions
    {
        public string ConnString { get; set; }
    }

注冊服務列表

    /// <summary>
    /// 注冊有關(guan)-EF倉(cang)儲的服務列表
    /// </summary>
    public class EFOptionsExtension : ILindOptionsExtension
    {
        private readonly Action<RepositoryOptions> _configure;

        public EFOptionsExtension(Action<RepositoryOptions> configure)
        {
            _configure = configure;
        }
        public void AddServices(IServiceCollection services)
        {
            services.AddSingleton(typeof(IRepository), typeof(EFRepository));
            var mysqlOptions = new RepositoryOptions();
            _configure(mysqlOptions);
        }
    }

在外部使用這個模塊(kuai),就是在Startup中注(zhu)冊它(ta)

  public static class RepositoryOptionsExtensions
  {
        public static LindOptions UseEF(this LindOptions options, Action<RepositoryOptions> configure)
        {
            options.RegisterExtension(new EFOptionsExtension(configure));

            return options;
        }
   }

四 在Startup.ConfigureServices中注冊自定(ding)義(yi)模塊

上(shang)面(mian)的(de)代(dai)碼主要是自定義(yi)一個模塊,而在startup中使用它,就(jiu)像(xiang)下面(mian)的(de)代(dai)碼,十分簡潔,當前有些配置(zhi)信(xin)息可(ke)以(yi)到在基于(yu)環(huan)境變量的(de)json文件(jian)里!

       public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddLind(x =>
            {
                x.UseEF(o =>
                {
                    o.ConnString = "localhost:1433";
                });
                x.UseDapper(o =>
                {
                    o.ConnString = "localhost:3306";
                });
            });
        }

五 在Startup.Configure中使用它(ta),進行默認模(mo)塊的初始(shi)化

上面的代碼(ma)實(shi)現(xian)了對模塊下(xia)一些服(fu)務進行注冊(ce),然后下(xia)面代碼(ma)主要是進行一些初始化的工(gong)作。

       public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            app.UseLind();
        }

六 在(zai)任意對象(xiang)的構(gou)造方法中使用它

當我們把服務注冊后,可(ke)以(yi)在任意(yi)類型的構造方法(fa)中(zhong)使用(yong)它,而不是只能(neng)在控(kong)制器中(zhong)使用(yong),這一點dotnetcore DI做的確實不錯,給(gei)它100個(ge)贊(zan)!

這種(zhong)注冊

    public class ApiLoggerOptionsExtension : IPilipaOptionsExtension
    {
        Action<ApiLoggerConfig> _config;
        public ApiLoggerOptionsExtension(Action<ApiLoggerConfig> config)
        {
            _config = config;
        }
        public void AddServices(IServiceCollection services)
        {
            ApiLoggerConfig apiLoggerConfig = new ApiLoggerConfig();
            _config(apiLoggerConfig);//裝飾
            services.AddSingleton(apiLoggerConfig);//注冊對(dui)象里的屬性,在對(dui)象的構造(zao)方法(fa)被注入
            services.AddSingleton(typeof(ILogger), typeof(ApiLogger));//注(zhu)(zhu)冊對(dui)象,在使用對(dui)象的類的構造方法被注(zhu)(zhu)入
        }
    }

這種使用

        ApiLoggerConfig _config;
        public ApiLogger(ApiLoggerConfig config)
        {
            _config = config;
        }

對于上面的代碼實現了在OptionsExtension里進行注冊,然后在任意類型(xing)中(zhong)使用它(ta),感覺這點(dian)確實靈活了(le)不少!

今天咱們對dotnetcore DependencyInjection的分享就到這里,希(xi)望(wang)大家(jia)也盡量(liang)把(ba)模(mo)塊從項目中(zhong)解放出來(lai)

感謝各位的閱讀!

回到目錄

posted @ 2017-10-11 17:36  張占嶺  閱讀(2661)  評論(4)    收藏  舉報