回到目录

写这篇文章的心情:激动

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的分享就到这里,希望大家也尽量把模块从项目中解放出来!

感谢各位的阅读!

回到目录

DotNetCore跨平台~一起聊聊Microsoft.Extensions.DependencyInjection的更多相关文章

  1. 解析 Microsoft.Extensions.DependencyInjection 2.x 版本实现

    项目使用了 Microsoft.Extensions.DependencyInjection 2.x 版本,遇到第2次请求时非常高的内存占用情况,于是作了调查,本文对 3.0 版本仍然适用. 先说结论 ...

  2. 使用诊断工具观察 Microsoft.Extensions.DependencyInjection 2.x 版本的内存占用

    目录 准备工作 大量接口与实现类的生成 elasticsearch+kibana+apm asp.net core 应用 请求与快照 Kibana 上的请求记录 请求耗时的分析 请求内存的分析 第2次 ...

  3. Microsoft.Extensions.DependencyInjection 之三:展开测试

    目录 前文回顾 IServiceCallSite CallSiteFactory ServiceProviderEngine CompiledServiceProviderEngine Dynamic ...

  4. Microsoft.Extensions.DependencyInjection 之三:反射可以一战(附源代码)

    目录 前文回顾 IServiceCallSite CallSiteFactory ServiceProviderEngine CompiledServiceProviderEngine Dynamic ...

  5. Microsoft.Extensions.DependencyInjection 之二:使用诊断工具观察内存占用

    目录 准备工作 大量接口与实现类的生成 elasticsearch+kibana+apm asp.net core 应用 请求与快照 Kibana 上的请求记录 请求耗时的分析 请求内存的分析 第2次 ...

  6. Microsoft.Extensions.DependencyInjection 之一:解析实现

    [TOC] 前言 项目使用了 Microsoft.Extensions.DependencyInjection 2.x 版本,遇到第2次请求时非常高的内存占用情况,于是作了调查,本文对 3.0 版本仍 ...

  7. 使用 Microsoft.Extensions.DependencyInjection 进行依赖注入

    没有 Autofac DryIoc Grace LightInject Lamar Stashbox Unity Ninject 的日子,才是好日子~~~~~~~~~~ Using .NET Core ...

  8. MvvmLight + Microsoft.Extensions.DependencyInjection + WpfApp(.NetCore3.1)

    git clone MvvmLight失败,破网络, 就没有直接修改源码的方式来使用了 Nuget安装MvvmLightLibsStd10 使用GalaSoft.MvvmLight.Command命名 ...

  9. Microsoft.Extensions.DependencyInjection中的Transient依赖注入关系,使用不当会造成内存泄漏

    Microsoft.Extensions.DependencyInjection中(下面简称DI)的Transient依赖注入关系,表示每次DI获取一个全新的注入对象.但是使用Transient依赖注 ...

随机推荐

  1. 通过业务系统的重构实践DDD

    最近新接了一个业务系统——社区服务系统,为了快速熟悉和梳理老系统的业务逻辑和代码,同时对老系统代码做一些优化,于是打算花上一个月时间不间断地对老系统服务进行重构.同时,考虑到社区业务的复杂性,想起了之 ...

  2. el-input监听不了回车事件

    vue使用element-ui的el-input监听不了回车事件,原因应该是element-ui自身封装了一层input标签之后,把原来的事件隐藏了,所以如下代码运行是无响应的: <el-inp ...

  3. chrome开发工具指南(五)

    Main Menu Click More  to open the Main Menu. Settings To open Settings, do one of the following: Pre ...

  4. select 标签选中 jquery

    网上很多错误 的[text ='xxx'] ,我晕. option 标签没有 text 属性.所以[]选取不到. 正确的: $("#yearCardTypeState option:cont ...

  5. 【Beta阶段】第二次scrum meeting

    Coding/OSChina 地址 1. 会议内容 学号 主要负责的方向 昨日任务 昨日任务完成进度 接下去要做 99 PM 会议总结,博客编写,代码整理 100% 准备下一次会议内容,并对已完成的代 ...

  6. spring的配置文件和加载

    ①:创建applicationContext.xml配置文件放在src下 //applicationContext.xml代码 <?xml version="1.0" enc ...

  7. 201521123056 《Java程序设计》第7周学习总结

    1. 本周学习总结 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 1.2 解释E remove(int index)源代码 1.3 结合1. ...

  8. 201521123017 《Java程序设计》第3周学习总结

    1. 本周学习总结 2. 书面作业 Q1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; ...

  9. 201521123013 《Java程序设计》第1周学习总结

    1. 本章学习总结 1.Java是面向对象的编程语言,它在通过jvm和jre将其转成本地机器代码,达到一次撰写,到处运行的效益,实现跨平台运行,代码开源,使用范围广. 2.了解jdk.jre.jvm的 ...

  10. Android中显示和隐式Intent的使用

    显示启动activity                                                                                         ...