跨平台的.NET邮件协议Mail基特组件解析

 

    2.邮件新闻的分析:

var message = MimeMessage.Load(stream);

 
 邮件的音信大家需要举行相应的分析,这里我们选取MimeMessage的Load方法,该办法从指定的流加载Mime基特(Kit).MimeMessage。另一个加载数据的点子,可以拔取MimeParser类,这里就不再解析了。

小效用的分段

 

咱俩以此小品种分四层,分别为

  • 特朗普(Trump).Domain 紧要存放在模型,不引用任何类型
  • 特朗普.EF 实现多少持久化内容,本案中应用EF6,所以这边会有大量EF
    CRUD实现的操作,看重Domain项目
  • 特朗普.Application
    实现数量与UI的互相,经过EF处理的多少在这一层转接为DTO重临到UI层,倚重Domain、EF项目
  • Trump.ExamApp UI层实现,使用MVC5+Web
    Api+jQuery+Bootstrap构建,依赖Domain、Application层。

一般项目中还会有一个援救类的品种,提供一些常用方法封装,增加方法等,并不作为任何项目独有,所以那边就不列出来了。

 

四.总结

 
 本人觉得在档次开支中,假诺引入了第三方组件,大家尽量引入组件的源码,这样大家对总体组件的协会有一个认识,组件的贯彻模式我们也可以拓展仔细领悟,尤其是大家在展开调试的事后愈来愈有用,大家得以逐一的举行断点调试。以上是对该零件的一个简约介绍,有趣味的可以去深刻的垂询和学习。

连串分层结构也要在此地说一下,本次那个小效能仿照DDD的分层情势,一定牢记我说的是模仿。因为自身也不懂DDD,我就画个皮。

    3.邮件的吸收:

   public static void HandleMimeEntity(MimeEntity entity)
        {
            //MimeEntity转化为Multipart实体
            var multipart = entity as Multipart;
            if (multipart != null)
            {
                for (int i = 0; i < multipart.Count; i++)
                    HandleMimeEntity(multipart[i]);
                return;
            }
            var rfc822 = entity as MessagePart;

            if (rfc822 != null)
            {
                var message = rfc822.Message;
                HandleMimeEntity(message.Body);
                return;
            }
            var part = (MimePart)entity;
        }

 
 以上是对接到到的信息的一个遍历,拔取递归遍历MIME结构。MIME是内容的树结构,很像一个文件系统。MIME确实定义了一组通用规则,用于邮件客户端怎么着解释MIME部分的树结构。的 内容处置头是为着给接受客户端提供提示以什么样部分是为了体现作为音讯体的一片段,并且目的在于被诠释为附件。其它二种方法这离就不做牵线了。

DDD这一个东西中文名字应该叫领域驱动设计,园子很多大神分享过、讲解过。看了许多博客很多书,仍然没太驾驭这么复杂的东西(没有履行,纸上得来终觉浅)。这里大概说说自己的知晓,把事情逻辑尽量的集中在领域层(Domain),假设项目是人体,这世界层就是人身的大脑了,以前天的科技,身上的零部件除了大脑基本都可替换。也许可以把大脑换来另一个人身上,然而,整个身子依然要听大脑的指挥。假使肢体没有了大脑,基本上就是一滩肉,失去了作为机体的效益。

  1.创办邮件格局:

 public void SentEmail(string path)
        {
            var message = new MimeMessage();
            //获取From标头中的地址列表,添加指定的地址
            message.From.Add(new MailboxAddress("Joey", "joey@friends.com"));
            //获取To头中的地址列表,添加指定的地址
            message.To.Add(new MailboxAddress("Alice", "alice@wonderland.com"));
            //获取或设置消息的主题
            message.Subject = "How you doin?";
            // 创建我们的消息文本,就像以前一样(除了不设置为message.Body)
            var body = new TextPart("plain")
            {
                Text = @"Hey Alice-- Joey"
            };
            // 为位于路径的文件创建图像附件
            var attachment = new MimePart("image", "gif")
            {
                ContentObject = new ContentObject(File.OpenRead(path), ContentEncoding.Default),
                ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                ContentTransferEncoding = ContentEncoding.Base64,
                FileName = Path.GetFileName(path)
            };
            // 现在创建multipart / mixed容器来保存消息文本和图像附件
            var multipart = new Multipart("mixed")
            {
                body, attachment
            };
            // 现在将multipart / mixed设置为消息正文 
            message.Body = multipart;
        }

 
 调用该零件发送邮件和为邮件添加附件是相比较简单的,第一步是实例化MimeMessage对象,对于该目的的解析将在底下举办,拿到MimeMessage对象后,指定邮件的地点和主旨等等相关音讯。第二步实例化TextPart对象,为对象设定文本音讯。若需要问邮件创设文件的附件,可以运用MimePart对象,包含内容(如信息正文文本或)的叶节点MIME部分一个附件。第四步为创立的邮件主体和文件以及附件新闻后,可以创建Multipart对象,创立邮件容器,用来装载文本音讯和附件。最后调用MimeMessage.body属性获取或设置信息的正文。

 

三.Mail基特(Kit)核心对象解析

 
 下边介绍了Email的基本操作就不做过多的介绍,在使用该器件时,较为的简练。这里就来看望该零件的品类结构和部分主干目的。类库结构有如下图:

图片 1

以一种领域专家、设计人员、开发人员都能清楚的通用语言作为互相互换的工具,在互换的进程中窥见世界概念,然后将这多少个概念设计成一个天地模型;
由世界模型驱动软件设计,用代码来实现该领域模型;

   发起的.NET
Core开源社团号召,进展的进度是本身要好也尚无想到的,很多园友都积极参加(尽管有些人由衷砸场子,假设以本人此前的宝脾气,这会相应被我打住院了吗,可是幸而是少数,做一件事总有人说好,也有人说是用麦德林话说“闹眼子”),.NET社区不是从未愿意共享文化的人,只是没有一个整机和可观的生态环境,总而言之希望国内的.NET发展更为强大。我在此间想到一句话“大家盼望自己可以做巨浪,但我们也愿意做巨浪来袭前的小浪”。

世界驱动设计的经典分层架构

图片 2

 
 下面扯淡完毕(我这人干正事前,都要将一部分闲聊的话,这多少个习惯改不掉了…)

技巧尚未高低,唯有符合不符合!当然,php是最好的言语,这是江湖真理!

一.Mailkit组件概述

 
 项目中应用Email的操作机会比较多,一般不怎么大一些的品种,都会接纳到邮件操作这一个操作。对于.NET邮件操作的机件和艺术相比较多,前几日大家就介绍一款邮件操作的组件Mail基特(Kit),这一个邮件组件是一个开源免费的,我们前日就来了解一下这多少个零部件的风味。Mime基特(Kit)意在通过尽可能接近地服从MIME规范来化解这多少个题目,同时还为程序员提供了一个异常容易使用的高档API。

 
 组件的协助的客户端类型相比较多,例如SMTP客户端、POP3客户端、IMAP客户端。该器件是一个跨平台的Email组件,该器件帮助.NET
4.0,.NET 4.5,Xamarin.Android,Xamarin.iOS,Windows Phone
8.1之类平台。该器件提供了一个MIME解析器,组件具备的分析特性灵活、性能高、很好的处理千头万绪的破碎的MIME格式化。Mime基特的属性实际上与GMime分外。

   该器件在安全性的依然相比高的,处理平安的不二法门较多,SASL认证、协理S /
MIME v3.2、协理OpenPGP、援助DKIM签名等等形式。Mailkit组件可以经过CancellationToken撤销相应的操作,CancellationToken传播应废除操作的关照,一个的CancellationToken使线程,线程池工作类型里面,或注销合作任务的目的。过实例化CancellationTokenSource对象来创设裁撤令牌,该对象管理从其CancellationTokenSource.Token属性检索的吊销令牌。然后,将撤除令牌传递到应该接受废除公告的即兴数量的线程,任务或操作。令牌无法用来启动废除。

  Mail基特组件补助异步操作,在内部编写的有关I/O异步操作的类。

开创解决方案及创设项目(Vs 2017)

来吧来吧,新建空白解决方案,然后添加MVC项目,名字叫Trump.ExamApp,那个很基础很基础的,只列一下注意点

1.挑选ASP.NET Web应用程序.NET Framework
,下边至极是风传中的跨平台版本。相比滞后,看了一回视频都是第几集。

图片 3

2.摘取MVC,同时勾选Web
API(不勾选亦可以,可以经过Nuget添加),身份验证这里选取不进行身份验证。()

图片 4

 

身份验证:

不开展身份验证:不采用net自带的地方管理

个人用户账号:集成Asp.Net Identity v2(.NET Framework) or v3+(.NET
Core)版本

图片 5

3.成立完毕后如图

图片 6

4.应用Nuget管理项目中的引用

在档次上右键,管理Nuget程序包,移除“Microsoft.ApplicationInsights”。Application
Insights 是可扩大的应用程序性能管理 (APM) 服务,可让 Web
开发人士在多个阳台上生成和管制采取。暂时用不到,可是package有少数个,习惯性移除掉,然后就是升迁一下除了jQuery外所有的包。

注意:因为兼容性问题,jQuery版本不要随便更改

图片 7

 

好了。到此截至,这些体系为主竣工,接下去就是依据预定的名字创办其他多少个序列,接纳品种为类库(.NET
Framework)。

 

都创制完毕后,刷新一下,然后生成解决方案。把Web项目安装为启动项目,F5起步调试,我们全部项目标作风基本搭建完毕。

 
 项目中为了及时的通信,有直接发多少到页面,也有接纳短信通知,也有我门明日介绍的邮件组件。我们今日的基本点任务就是讲师一下有一个.NET的免费开源的邮件组件Mail基特(Kit)。本文将依然的整合实例和零部件底层代码讲解一下相关组件的知识。(项目招人的时候,我都会问一下.NET的最底层原理,有一个大神问我这么有怎么着意思呢?大家也写不出.NET底层这样的好好处理情势,为什么取明白这多少个,其实我个人认为,问底层的法则,只是向为了跟好的处理局部程序现身的题材,以及对先后编码的时候,接纳最合适的法子提高性能,任何一种方法都有优势和劣势,.NET的类库代码也是如此,假诺我们知道.NET的平底实现,大家在类型的需要实现时,可以依照.NET底层实现,选拔恰当的不二法门,以求性能最优)。

要详细询问DDD的定义可以打开下面的链接,包括下方图片,也是从小说中粘过来的,在此我们只是用他的分层,并没有举行DDD。

    1.MimeMessage.Load():

public static MimeMessage Load (ParserOptions options, Stream stream, bool persistent, 
                                CancellationToken cancellationToken = default (CancellationToken))
        {
            if (options == null)
                throw new ArgumentNullException (nameof (options));

            if (stream == null)
                throw new ArgumentNullException (nameof (stream));

            var parser = new MimeParser (options, stream, MimeFormat.Entity, persistent);

            return parser.ParseMessage (cancellationToken);
        }

   
 该措施从指定的流加载MimeMessage,具有6个办法重载。该办法再次回到一个MimeMessage对象,有源码可以看到,在该模式内部成立了一个MimeParser对象,MimeParser包含内容(例如邮件正文文本或附件)的叶节点MIME部分。调用ParseMessage方法,解析来自流的信息。

   2.TextPart.Text:

public string Text {
            get {
                if (ContentObject == null)
                    return string.Empty;
                var charset = ContentType.Parameters["charset"];
                using (var memory = new MemoryStream ()) {
                    ContentObject.DecodeTo (memory);
                    var content = memory.ToArray ();
                    Encoding encoding = null;
                    if (charset != null) {
                        try {
                            encoding = CharsetUtils.GetEncoding (charset);
                        } catch (NotSupportedException) {
                        }
                    }
                    if (encoding == null) {
                        try {
                            return CharsetUtils.UTF8.GetString (content, 0, (int) memory.Length);
                        } catch (DecoderFallbackException) {
                            encoding = CharsetUtils.Latin1;
                        }
                    }
                    return encoding.GetString (content, 0, (int) memory.Length);
                }
            }
            set {
                SetText (Encoding.UTF8, value);
            }
        }

   
该属性获取解码的文件内容。该属性是一个可读可写的性质。ContentType.Parameters[“charset”]用来获取charset参数的值。该方法用来将参数的值设置为数据流并设置相应的编码。看到此间的不得了处理协会,就想大概的谈几句,.NET的分外相比的软弱,很多时候在写.NET的十分时就更是的简单,以上是对丰富知识捕获,有些地点并不曾做处理,有些地点是对分外的地点举办复苏。

有鉴于此,领域驱动设计的主干是白手起家正确的领域模型

二.MailKit实例:

   
上边介绍了Mail基特(Kit)组件的背景和特性,这里就介绍一下Email组件的简练利用。

例如我们这一个系列,就是一个小的效率,现在可预估的用户量就是你我她,你非要在还没上线没成型就考虑百万级用户的扩张,揣度这些类型永远都没法上线了。

   3.MimeEntity.WriteTo():

public virtual void WriteTo (FormatOptions options, Stream stream, bool contentOnly, 
                            CancellationToken cancellationToken = default (CancellationToken))
        {
            if (options == null)
                throw new ArgumentNullException (nameof (options));

            if (stream == null)
                throw new ArgumentNullException (nameof (stream));

            if (!contentOnly)
                Headers.WriteTo (options, stream, cancellationToken);
        }

   
该措施将MimeEntity写入到指定的数目流中,该模式接受参数options格式选项。stream输出数据流,contentOnly判断是否可写。该方法定义为虚方法,在此起彼伏此办法后,可以在子类种对该措施举办重写。

一般一个品类上马在此以前都会有启动会,需求交底等等,其中会有一个环节,大讲特讲项目的意思,然后取一个高大上的系列名字,咱这是一个小功效谈不上体系,不过名字不可能太吝啬了。好啊,就叫Trump吧。没有任何意义,玩嘛!

此外作为一个机体,还远远没有达到想电脑这样的低耦合度,所以大部分零部件更换的老本都很高。即便是一台总计机,要转换零件也是要考虑到全体平台的架构等等信息,所以谈到低耦合,可替换的时候在不是迫于意况下,使用的几率很小。

置于项目上的一个例子,比如引入工作单元、仓储层的定义,就是为了隔离领域与数量持久化,然而真正项目上线,要替换数据持久化的那一层谈何容易。基于项目现有应用场景,然后开展技能选型的时候,要综合支出功用,开发成本,可扩充性,可维护性等等,并不是怎样惊天动地上就用哪些,什么概念都要涉及,这样只会变成一场技术点堆砌而难以实际利用。