回目录

写就首稿子的情绪:激动

Microsoft.Extensions.DependencyInjection在github上同是开源之,它于dotnetcore里被大面积的行使,比从之前的autofac,unity来说,它可说凡是只包,或者为适配器,它好提供了默认的DI实现,同时也支撑第三方的IOC容器,在即时段时间里采取了它,就想,这东西怎么让当dotnetcore里大放异彩?为什么会全程采用它们?从程序的始至程序启动起来,你可发现其无处不在,在框架里是这般,在业务层同时为是这么。

聊聊Microsoft.Extensions.DependencyInjection知识点包括

  1. 其的开源地址
  2. IServiceCollection和IApplicationBuilder
  3. 于定义模块用它
  4. 每当Startup.ConfigureServices中注册于定义模块
  5. 于Startup.Configure中应用它们,进行默认模块的初始化
  6. 以随机对象的构造方法中运用它们

如出一辙步一步的揭露

相同 它的开源地址

https://github.com/aspnet/DependencyInjection

得望她的README.md,就懂得其是个要命包,类似于父辈LindAgile里的Container,完全可扩展支持任何第三正在的IOC容器,这就是如大爷经常说的那么句话一样,在IT江湖面临,英雄总是所风略同……

老二
dotnetcore整个框架在用它

当公的dotnetcore应用程序里,你见面发现于Startup类中发出无数像services.AddMvc()这样的章程,这实质是像应用程序中注册一个零部件,这里的MVC是一个集合之零件,它不借助让windows,不借助于让dotnet,整个dotnetcore里把成千上万组件都解耦了,这样以维护和nuget包升级时都再度活,自己生题目不怕优化自己,而未影响其他模块。(越说尤其像微服务的宗旨)。

IServiceCollection主要用于注册服务,就是某个接口及某种实现之附和关系,这种注册是咱以Startup.ConfigureServices方法里就的,如下面的AddLind()这个方法,它形成了对Lind模块的挂号,在法中可以登记本模块的任何服务。

        /// <summary>
        /// 添加Lind框架和它们依赖子模块
        /// </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();
            //注册框架所依赖的基础模块
            //options.Extensions.Add();
            //注册外部模块
            setupAction(options);
            foreach (var serviceExtension in options.Extensions)
                serviceExtension.AddServices(services);
            services.AddSingleton(options);
            return new LindBuilder(services);
        }

IApplicationBuilder是凭对该程序的启航,或者了解呢初始化,当上面的劳务注册就后就尽其了,我们一般以Startup.Configure去激活它,它的目的比较才,就是对模块进行初始化,如果没什么异常之功用,这个代码可以是拖欠的,下面Builder中初始化了日志组件。

        /// <summary>
        /// 在应用程序中开启-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;
        }

其三 自定义模块用它

假使期待定义自己之功能模块实现和dotnetcore框架的结合得自定义Options和OptionsExtensions,前者主要实现的是劳动列表的登记,而后台重要是指向现有模块提供注册的输入,下面的代码主要实现了一个EF仓储模块的注册过程。

模块所待的范

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

挂号服务列表

    /// <summary>
    /// 注册有关-EF仓储的服务列表
    /// </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);
        }
    }

每当外表使用这模块,就是当Startup中注册它

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

            return options;
        }
   }


在Startup.ConfigureServices中登记由定义模块

地方的代码主要是自从定义一个模块,而于startup中运用其,就如下的代码,十分简短,当前微配置信息可交于依据环境变量的json文件里!

       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中使用它,进行默认模块的初始化

面的代码实现了针对性模块下部分劳动进行登记,然后下代码主要是开展一些初始化的干活。

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

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


在肆意对象的构造方法中使用其

当我们将劳务注册后,可以当任意档次的构造方法中行使它们,而非是只能于控制器中以,这无异接触dotnetcore
DI做的的确不易,给它们100单赞!

这种注册

    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);//注册对象里的属性,在对象的构造方法被注入
            services.AddSingleton(typeof(ILogger), typeof(ApiLogger));//注册对象,在使用对象的类的构造方法被注入
        }
    }

这种应用

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

对此地方的代码实现了在OptionsExtension里展开挂号,然后以任意档次受到动用它们,感觉立马点真灵活了无数!

今天我们对dotnetcore DependencyInjection的分享就交这边,希望大家呢尽可能将模块于项目中解放出来!

谢各位的读书!

归来目录

相关文章

网站地图xml地图