回到目录

一步一步的揭破

一 它的开源地址

https://github.com/aspnet/DependencyInjection

可以看看它的README.md,就了解它是个大包裹,类似于父辈LindAgile里的Container,完全可以增添扶助其他第三方的IOC容器,这就像二叔平常说的那句话一样,在IT江湖中,英雄总是所风略同……

图片 1


dotnetcore整个框架在用它

在您的dotnetcore应用程序里,你会发觉在Startup类中有诸多像services.AddMvc()这样的方法,这精神是像应用程序中登记一个零部件,这里的MVC是一个统一的零部件,它不借助于于windows,不依靠于dotnet,整个dotnetcore里把成千上万组件都解耦了,这样在保安和nuget包升级时都更灵活,自己有题目就优化自己,而不影响其余模块。(越说越像微服务的主题)。

I瑟维斯(Service)Collection重要用来注册服务,就是某个接口和某种实现的照应关系,这种注册是我们在Startup.Configure瑟维斯(Service)s方法里做到的,如下边的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.Configure瑟维斯(Service)s中注册自定义模块

下边的代码重假设自定义一个模块,而在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的享受就到这边,希望我们也尽可能把模块从序列中解放出来!

感谢各位的阅读!

回去目录

写这篇作品的心境:激动

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

  1. 它的开源地址
  2. IServiceCollection和IApplicationBuilder
  3. 自定义模块用它
  4. 在Startup.Configure瑟维斯(Service)(Service)s中注册自定义模块
  5. 在Startup.Configure中行使它,举办默认模块的开首化
  6. 在随机对象的构造方法中使用它

Microsoft.Extensions.DependencyInjection在github上亦然是开源的,它在dotnetcore里被广泛的行使,比起在此以前的autofac,unity来说,它可以说是个包裹,或者叫适配器,它自己提供了默认的DI实现,同时也补助第三方的IOC容器,在那段时光里拔取了它,就想,这东西怎么被在dotnetcore里大放异彩?为何会全程采纳它?从程序的启幕到程序启动起来,你可以发现它无处不在,在框架里是这般,在业务层同时也是这样。

相关文章

网站地图xml地图