MEF 插件幸运飞艇平台出租式开发 - DotNetCore 中强大的 DI

背景叙述
在前面几篇幸运飞艇平台出租(www.1159880099.com)QQ1159880099 MEF 插件式开发 系列博客中,我分别在 DotNet Framework 和 DotNet Core 两种框架下实验了 MEF 的简单实验,由于 DotNet Framework 由来已久,因此基于该框架下衍生出的很多优秀的 MEF 框架较多。但是对于 DotNet Core 来说,情况有所不同,由于它本身对 DI 内置并提供支持,因此我尝试使用它的全新 依赖注入(DI) 来做一些实验。

动手实验
要想让程序支持 DI,就需要为项目安装 Package:

Install-Package Microsoft.Extensions.DependencyInjection -Version 2.1.1
然后,我们就可以使用强大的 DI 了。

在 DotNet Core,所有服务的注册都是统一放到一起的,而这个就是由 ServiceCollection 来接收的;其次,当服务注册完毕后,还需要对服务进行初始化构建,构建后的结果作为一个提供服务者返回,其对应的类型为 ServiceProvider;最后,如果获取某个已经注册的服务的话,可以通过 serviceProvider.GetService() 来获取。

下面,我分别从下面 4 个方面来体验一下 DotNet Core 中强大的 DI。

注入并设置服务的生命周期
注册服务需要涉及到服务的生命周期,因此,IServiceCollection 有 3 个不同的扩展方法:

AddTransient:每次获取的服务都是新创建的;
AddScoped:在一定范围内获取的服务是同一个;
AddSingleton:每次获取的服务都是同一个,单例模式的服务;
示例代码如下所示:

public interface IBaseSender
{
void Send(string message);

}

public interface ITransientSender : IBaseSender { }
public class TransientSender : ITransientSender
{
public void Send(string message) => Console.WriteLine($"{GetHashCode()} {message}");
}

public interface IScopedSender : IBaseSender { }
public class ScopedSender : IScopedSender
{
public void Send(string message) => Console.WriteLine($"{GetHashCode()} {message}");
}

public interface ISingletonSender : IBaseSender { }
public class SingletonSender : ISingletonSender
{
public void Send(string message) => Console.WriteLine($"{GetHashCode()} {message}");
}

class Program
{
private static readonly object locker = new object();
static void Main(string[] args)
{
var serviceProvider = new ServiceCollection()
.AddTransient<ITransientSender, TransientSender>()
.AddScoped<IScopedSender,ScopedSender>()
.AddSingleton<ISingletonSender, SingletonSender>()
.BuildServiceProvider();

    using (var scope = serviceProvider.CreateScope())
    {
        for (int i = 0; i < 2; i++)
        {
            serviceProvider.GetService<ITransientSender>().Send("ITransientSender");
            scope.ServiceProvider.GetService<IScopedSender>().Send("IScopedSender");
            serviceProvider.GetService<ISingletonSender>().Send("ISingletonSender");
        }
    }
    Console.WriteLine("***********************************");
    using (var scope = serviceProvider.CreateScope())
    {
        for (int i = 0; i < 2; i++)
        {
            serviceProvider.GetService<ITransientSender>().Send("ITransientSender");
            scope.ServiceProvider.GetService<IScopedSender>().Send("IScopedSender");
            serviceProvider.GetService<ISingletonSender>().Send("ISingletonSender");
        }
    }

    Console.ReadKey();
}

}
程序输出如下图所示:

通过上图我们可以了解到,

在相同或不同的作用域内,通过 AddTransient 注册的服务每次都是新创建的;
在相同作用域内,通过 AddScoped 注册的服务每次同一个;在不同请求作用域中,通过 AddScoped 注册的服务每次都是新创建的;
通过 AddSingleton 注册的服务在整个程序生命周期内是同一个;
需要注意的是,在 ASP.NET Core 中,所有与 EF 相关的服务都应该通过 AddScoped<TInterface,T> 的方式注入。此外,如果想注入泛型的话,可借助 typeof方式来注入。

构造函数注入
参数注入

public interface IBaseSender
{
void Send();
}

public class EmialSender : IBaseSender
{
private readonly string _msg;
public EmialSender(string msg) => _msg = msg;

public void Send() => Console.WriteLine($"{_msg}");

}

class Program
{
static void Main(string[] args)
{
var serviceProvider = new ServiceCollection()
.AddSingleton<IBaseSender, EmialSender>(factory => { return new EmialSender("Hello World"); })
.BuildServiceProvider();

    serviceProvider.GetService<IBaseSender>().Send();

    Console.ReadKey();
}

}
服务注入

public interface IBaseSender
{
void Send();
}

public class EmialSender : IBaseSender
{
private readonly IWorker _worker;
public EmialSender(IWorker worker) => _worker = worker;

public void Send() =>_worker.Run("Hello World");

}

public interface IWorker
{
void Run(string message);
}

public class Worker : IWorker
{
public void Run(string message)
{
Console.WriteLine(message);
}
}

class Program
{
private static readonly object locker = new object();
static void Main(string[] args)
{
var serviceProvider = new ServiceCollection()
.AddSingleton<IBaseSender, EmialSender>()
.AddSingleton<IWorker, Worker>()
.BuildServiceProvider();

    serviceProvider.GetService<IBaseSender>().Send();

    Console.ReadKey();
}

}
在传统的DotNet 框架下开发,注入是支持 参数、服务和属性的,但是在 DotNet Core 平台下目前只支持前两种注入方式。

添加日志记录
DotNet Core 中已经将 Logger 功能集成进来,只需要安装相应的 Package 即可食用。

Microsoft.Extensions.Logging
Microsoft.Extensions.Logging.Console
Microsoft.Extensions.Logging.Debug
示例程序如下所示:

public interface IBaseSender
{
void Send();
}

public class EmialSender : IBaseSender
{
private readonly IWorker _worker;
private readonly ILogger<EmialSender> _logger;

public EmialSender(IWorker worker, ILogger<EmialSender> logger)
{
    _worker = worker;
    _logger = logger;
}

public void Send()
{
    _worker.Run("Hello World");
    _logger.LogInformation(MethodBase.GetCurrentMethod().Name);
}

}

public interface IWorker
{
void Run(string message);
}

public class Worker : IWorker
{
public void Run(string message)
{
Console.WriteLine(message);
}
}

class Program
{
private static readonly object locker = new object();
static void Main(string[] args)
{
var serviceProvider = new ServiceCollection()
.AddSingleton<IBaseSender, EmialSender>()
.AddSingleton<IWorker, Worker>()
.AddSingleton(new LoggerFactory().AddConsole().AddDebug())
.AddLogging()
.BuildServiceProvider();

    serviceProvider.GetService<IBaseSender>().Send();

    Console.ReadKey();
}

}
总结
这次做的几个小实验还是很有趣的,体验了一下 DotNet Core 中强大的 DI 功能。和传统的 DotNet Framework 相比,有很多改进的地方,这是值得每一个 DotNet 程序员 去尝试的一门新技术。

原文地址:http://blog.51cto.com/13922710/2159709

时间: 2024-10-12 00:08:41

MEF 插件幸运飞艇平台出租式开发 - DotNetCore 中强大的 DI的相关文章

Java的业务OA幸运飞艇平台出租逻辑验证架fluent-validator

在互联网OA幸运飞艇平台出租haozbbs.comQ1446595067 行业中,基于Java开发的业务类系统,不管是服务端还是客户端,业务逻辑代码的更新往往是非常频繁的,这源于功能的快速迭代特性.在一般公司内部,特别是使用Java web技术构建的平台中,不管是基于模块化还是服务化的,业务逻辑都会相对复杂. 这些系统之间.系统内部往往存在大量的API接口,这些接口一般都需要对入参(输入参数的简称)做校验,以保证:1) 核心业务逻辑能够顺利按照预期执行.2) 数据能够正常存取.3) 数据安全性.

机器学习实践心得:数据平台设计与搭建US幸运飞艇平台出租

机器学习作为近几年的一项热门技术US幸运飞艇平台出租QQ2952777280[话仙源码论坛]hxforum.com[木瓜源码论坛]papayabbs.com,不仅凭借众多"人工智能"产品而为人所熟知,更是从根本上增能了传统的互联网产品.下文将基于本人所负责的个推大数据平台搭建工作,与大家分享个推数据平台架构方面的经验以及踩过的一些坑. 一.背景:机器学习在个推业务中的应用场景作为独立的智能大数据服务商,个推主要业务包括开发者服务.精准营销服务和各垂直领域的大数据服务.而机器学习技术在多

功能、界面/易用性幸运飞艇平台出租、中断、网络、兼容性、安全性、性能测试

功能测试幸运飞艇平台出租(www.1159880099.com)QQ11598800991.朋友圈发送功能 1)只发送文本 a.考虑文本长度:1-1500字符(该数据为百度数据).超出最大字符长度 b.考虑文本类型:纯中文.纯数字.纯字母.纯字符.纯表情(微信表情/手机自带表情).混合类型.包含url链接:因为过长纯类型需要换行很容易出现超出边框问题,所以这里先考虑过长纯类型情况 c.文本是否支持复制粘贴 d.为空验证 2)只发送图片 a.本地相册选择/拍摄 b.图片数量验证:1-9张图片.超出

利用padding-top/padding-bottom百分比OA幸运飞艇平台,进行占位和高度自适应

在css里面,padding-top,padding-bottom,margin-top,margin-bottom取值为百分比的时候,参照的是父元素的宽度. 比如:父元素宽度是100px, 子元素padding-top:50%,那么padding-top的实际值就是100*50%=50px 这个小小的知识点,其实有很大的用处,应用也很广泛,就是进行提前占位,避免资源加载时候的闪烁,还可以让高度自适应. 举例: 一般来说,想要自适应屏幕大小,我们设置元素的宽度自适应是完全没有问题的,比如希望一行

Linux中用Nginx和FTP搭建WS幸运飞艇平台搭建图片服务器

一.需要的组件WS幸运飞艇平台搭建论坛:haozbbs.com Q1446595067 图片服务器两个服务:Nginx(图片访问): 1.http服务:可以使用nginx做静态资源服务器.也可以使用apache.推荐使用nginx,效率更高. 2.反向代理 实现 负载均衡ftp服务(图片上传): 使用linux做服务器,在linux中有个ftp组件vsftpd.二.Nginx服务器搭建1.安装Nginx 要求安装vmware虚拟机. Linux:CentOS6.4(32) Nginx:1.8.0

Python爬虫爬取OA幸运飞艇平台获取数据

安装BeautifulSoup以及requests 打开window 的cmd窗口输入命令pip install requests 执行安装,等待他安装完成就可以了 BeautifulSoup库也是同样的方法 我使用的编译器的是sublime text 3,觉得是挺好用的一个编译软件 其他工具: Chrome浏览器 Python版本: Python3.6 运行平台: Windows 1.首先我们搜索OA幸运飞艇平台排行榜:[×××.com/h5]企 娥:217 1793 408获取网页的代码:

python paramiko模块幸运飞艇平台搭建实现跨平台SSH

需求:在幸运飞艇平台搭建论坛:haozbbs.com Q1446595067 管理用户端(实际上所有支持Python的OS都可以)批量对远程服务器进行部署.命令执行.文件传输.搭建测试环境等. 一般的,我们用Putty,Xshell,Winscp都可以实现SSH登录,但是如果出现N台服务器,我们按照原来的方法,需要逐个登录配置,这会花费一定的时间.实际上,Python的paramiko模块就可以实现这种操作.其原理就是模拟SSH客户端,与SSH服务端进行交互,实现登录与命令的实时传输.Param

Java创建极速飞艇平台出租线程的三种方式

(1)定义Thread类的子类,极速飞艇平台出租[企鹅21717-93408]并重写该类的run方法,该run方法的方法体就代 表了线程要完成的任务.因此把run()方法称为执行体.(2)创建Thread子类的实例,即创建了线程对象.(3)调用线程对象的start()方法来启动该线程. 二.通过Runnable接口创建线程类(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体是该线程的线程执行体.(2)创建 Runnable实现类的实例,并依此实例作为T

Java8函数OA现金盘平台出租式编程实践精华

现在是OA现金盘平台出租haozbbs.comQ1446595067 资源共享的时代,同样也是知识分享的时代,如果你觉得本文能学到知识,请把知识与别人分享. 绪论 从java8开始,我们就可以通过java8中的StrameAPI与Lambda表达式实现函数式编程,可以让代码变得更加高效简洁. 现在很多企业的生产代码已经开始使用java8了,对于还没有使用过java8进行的编程的朋友们可以好好的学习一下,我在企业中写java8也有一段时间了,我想把我在实际开发中用到的一些场景与大家分享一下,大部分