新普金娱乐网址


地理泛泛谈崖柏——如何自崖柏毛料上辨别料质的好坏?

相同片玻璃的秘密之同

C#开发微信门户及应用(42)–使用Autofac实现微信接口处理的操纵反转处理

  • 九月 24, 2018
  • 地理
  • 没有评论

文章版权由作者李晓晖同博客园共有,若转载请让大庭广众处于标明出处:http://www.cnblogs.com/naaoveGIS/。

当广大情况下,我们运用IOC控制反转可以好便利实现部分接口的适配处理,可以在得的早晚切换不同之接口实现,使用这种方式于调用的时光,只需要懂得相应的接口接口,具体调用哪个实现类似,可以以安排文件中动态指定,本篇主要介绍AutoFac的IOC组件的应用,用来贯彻微信接口处理的控制反转功能。

1.    前言

俺们在达成同章节里了解及WebGIS中栅格图层的实质——地图图片。而起前面的第二节及第五段,我们详细的介绍了地图图片的获取原理和法。所以当规划栅格图层前,我们就亮了栅格图层中数据是哪获得的,剩下的就算是安用之进程用同一栽符合面向对象的规划原则来拓展落实。

咱们解,实现IOC的不二法门有许多,如Unity、AutoFac、Ninject、Castle
Windsor、Spring.NET等等,每种IOC组件都产生谈得来的组成部分特性,我于前头的实业框架随笔系列介绍了Unity的运《Entity
Framework
实体框架的变异的一起–利用Unity对象依赖注入优化实体框架(2)》,本来为想就此这来促成微信的接口调用处理,不过鉴于其版本与有任何问题,总是没那么方便,最后决定采取啊正如流行,应用较多之的AutoFac组件来贯彻。

2.栅格数据获得的流程

这里自己再也将栅格数据获得的流水线描述一百分之百:

首先,得到屏幕范围外之地形图四竞技坐标,根据此四较量坐标算有屏幕范围外地图太贴近的地形图级别,以及这瓦片的行号范围以及列号范围,然后按照行号和列号拼接出瓦片请求,进行瓦片加载。最后用得到的瓦片按照顺序拼接成一整块地形图,进而于前者显示出。

1、微信接口的处理要求

咱们于以微信公众号实现有作业处理的时候,往往需要根据不同之格进行不同的接口调用。

要通过二维码扫码的结果处理,然后呈现给微信用户之连带信息,有下面两种办法。

图片 1

依据用户的扫码结果,我们好打定义自己的事务处理,然后呈现给用户,那么这里运用IOC来贯彻具体的政工是较好的,我们以具体的业务实现中,可以因不同之基准实现所需要之繁杂处理。

图片 2

自然我们还得扩展及老多的事务接口里面,如百度的地理位置分析接口、电影院信息查询、天气信息查询、交通信息查询、旅游信息查询等,还有短信、邮件发送等常规接口,都足以以这种办法进行处理。

接口的效用亮如下所示。

图片 3

这些让其它类别模块使用的时刻,我们好以配置文件中指定具体的接口实现信息,这种可切实指定所需要的落实。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
  </configSections>
  <autofac defaultAssembly="WHC.Common.Handler">
    <components>
      <component type="WHC.Common.Handler.TestHandler, WHC.Common.Handler" service="WHC.Common.Handler.ITestHandler" />
      <component type="WHC.Common.Handler.QRCodeHandler, WHC.Common.Handler" service="WHC.Common.Handler.IQRCodeHandler" />
      <!--邮件短信-->
      <component type="WHC.Common.Handler.SmsSendHandler, WHC.Common.Handler" service="WHC.Common.Handler.ISmsHandler" />
      <component type="WHC.Common.Handler.MailSendHandler, WHC.Common.Handler" service="WHC.Common.Handler.IMailHandler" />

    </components>
  </autofac>
</configuration>

直接使用AutoFac的操作应该是较好,使用接口获取方式取具体实现即得了。

 

3.实际上被的问题

计划前面我们提出这样一个题目:

俺们栅格数据的源于或产生多栽,比如在线地图和离线地图。同时,在线地图可能是出于不同之请求方式使取得的数,离线地图为一样或是出自于不同之切图格式。

咱俩己是未能够确定用户以啊一样种多少来源于,或者用户是否会面中途改变多少来自。

2、使用Autofac实现

为方便使用Autofac,我们得先行以项目达的Nuget包管理,引用相关的DLL,其中囊括核心的Autofac类库,以及读取配置文件的Autofac
Configuration,后者为方便读取XML配置信息所必须。

图片 4

引入这半独DLL就足以采取Autofac的法力了。

相似经过配备文件,初始化的Autofac组件的代码如下所示

    instance = new AutoFactory();

    //初始化相关的注册接口
    var builder = new ContainerBuilder();
    //从配置文件注册相关的接口处理
    builder.RegisterModule(new ConfigurationSettingsReader("autofac", configurationFile));
    container = builder.Build();

如果我们下Autofac的接口也是异常爱的,常规的运代码如下所示。

            var handler = container.Resolve<ITestHandler>();
            handler.Test("测试");

自,为了有利于,我们可采取一个辅助类来简化这接口的调用:在辅助类初始化的时刻,我们打部署文件加载对应之机件接口实现,当我们要分析具体接口的时,就得一直由Container容器里面胡获取了,辅助类代码如下所示。

    /// <summary>
    /// 使用AutoFac的工厂类,通过配置
    /// </summary>
    public class AutoFactory
    {
        //普通局部变量
        private static object syncRoot = new Object();
        //工厂类的单例
        private static AutoFactory instance = null;
        //配置文件
        private const string configurationFile = "autofac.config";

        /// <summary>
        /// IOC的容器,可调用来获取对应接口实例。
        /// </summary>
        public IContainer Container { get; set; }

        /// <summary>
        /// IOC容器工厂类的单例
        /// </summary>
        public static AutoFactory Instatnce
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            instance = new AutoFactory();

                            //初始化相关的注册接口
                            var builder = new ContainerBuilder();
                            //从配置文件注册相关的接口处理
                            builder.RegisterModule(new ConfigurationSettingsReader("autofac", configurationFile));
                            instance.Container = builder.Build();
                        }
                    }
                }
                return instance;
            }
        }

        /// <summary>
        /// 测试的接口
        /// </summary>
        public void Test()
        {
            var handler = AutoFactory.Instatnce.Container.Resolve<ITestHandler>();
            handler.Test("测试");
        }
    }

 

4.思路

细分析者提出的题材,结合面向对象设计受到之接续、封装、多态三独性状,我们可抽象出这般的相同种设计思路:

(1)设计一个近似,此类为有的栅格图层最高的父类——BaseLayer。在此类中定义有具有类似都需的因素,同时提供极基础之措施,比如事件监听方法。

(2)设计一个过于的近乎——ImageLayer,此类继承于BaseLayer,但是于此类中针对片联合的法门开展落实。比如瓦片的请求被,行号和列号是每一样栽栅格图层均用一些,并且瓦片的拼凑方式为是通用的。所以是因为当时几乎独共同点,可以定义有与此相关的不二法门。

(3)设计具体的栅格图层类,比如设计针对于ArcGIS在线地图的近乎、针对让超图在线地图的接近、针对于WMS请求方式的类似等等。而这些现实类都延续给ImageLayer。

3、外部接口实现同调用

这般咱们有着的接口都定义好,并受每个定义之接口相应个实现就足以应用这Autofac组件进行调用了。

    /// <summary>
    /// 短信发送接口
    /// </summary>
    public interface ISmsHandler
    {               
        /// <summary>
        /// 发送短信
        /// </summary>
        /// <param name="content">短信内容</param>
        /// <param name="mobiles">手机号码(多个号码用”,”分隔)</param>
        /// <param name="sendTime">预约发送时间</param>
        /// <returns></returns>
        CommonResult Send(string content, string mobiles, DateTime? sendTime = null);

        /// <summary>
        /// 查询剩余条数
        /// </summary>
        /// <returns></returns>
        CommonResult GetLeftCount();
    }

    /// <summary>
    /// 邮件发送接口
    /// </summary>
    public interface IMailHandler
    {              
        /// <summary>
        /// 发送外部邮件(自定义邮件配置,如个人邮件)
        /// </summary>
        /// <param name="mailInfo">发送邮件信息</param>
        /// <param name="settingInfo">SMTP协议设置信息</param>
        /// <returns></returns>
        CommonResult Send(MailInfo mailInfo, SmtpSettingInfo settingInfo);

        /// <summary>
        /// 发送外部邮件(系统配置,系统邮件)
        /// </summary>
        /// <param name="mailInfo">发送邮件信息</param>
        /// <returns></returns>
        CommonResult Send(MailInfo mailInfo);
    }

诸如,测试发送短信和邮件的IOC调用代码如下所示

            //使用IOC模块发送
            var sms = AutoFactory.Instatnce.Container.Resolve<ISmsHandler>();
            var smsTemplate = string.Format("验证码:{0}。尊敬的会员,您好,您正在注册会员,验证码2分钟内有效,感谢您的支持。", new Random().Next(100000));
            var result = sms.Send(smsTemplate, "18620292076");
            Console.WriteLine(result.Success ? "发送短信成功" : "发送短信失败:" + result.ErrorMessage);

            MailInfo info = new MailInfo();
            info.ToEmail = "wuhuacong@163.com";
            info.FromEmail = "wuhuacong@163.com";
            info.Subject = "这是一份来自我自己的测试邮件";
            info.Body = info.Subject + ",这是内容部分。<a href='http://www.iqidi.com'>点击这里返回主页</a>";
            var mail = AutoFactory.Instatnce.Container.Resolve<IMailHandler>();

            var mailResult = mail.Send(info);
            Console.WriteLine(mailResult.Success ? "发送邮件成功" : "发送邮件失败:" + mailResult.ErrorMessage);

测试后获的结果如下:

图片 5

邮件结果一致可以收到。

图片 6

咱回到地方介绍的第二维码扫描的作业实现力量,上面提到了,一个二维码事件可以派生出不同的接口实现,从而让不同的响应信息。

图片 7

    /// <summary>
    /// 扫码进行的处理
    /// </summary>
    public interface IQRCodeHandler
    {
        /// <summary>
        /// 处理ScancodePush的事件
        /// </summary>
        /// <param name="info">扫描信息</param>
        /// <param name="accountInfo">账号信息</param>
        /// <returns></returns>
        string HandleScancodePush(RequestEventScancodePush info, AccountInfo accountInfo);

        /// <summary>
        /// 处理ScancodeWaitmsg的事件
        /// </summary>
        /// <param name="info">扫描信息</param>
        /// <param name="accountInfo">账号信息</param>
        /// <returns></returns>
        string HandleScancodeWaitmsg(RequestEventScancodeWaitmsg info, AccountInfo accountInfo);
    }

我们可以定义两只简单的接口处理,用来承载微信二维码扫描接口的拍卖操作。

这般咱们当拍卖二维码扫描事件之上,我们尽管好把它分配至接口里面进行拍卖即可。

        /// <summary>
        /// 扫码推事件的事件推送处理
        /// </summary>
        /// <param name="info">扫描信息</param>
        /// <returns></returns>
        public string HandleEventScancodePush(RequestEventScancodePush info, AccountInfo accountInfo)
        {
            string result = "";
            var handler = AutoFactory.Instatnce.Container.Resolve<IQRCodeHandler>();
            if(handler != null)
            {
                result = handler.HandleScancodePush(info, accountInfo);
            }
            return result;
        }

        /// <summary>
        /// 扫码推事件且弹出“消息接收中”提示框的事件推送的处理
        /// </summary>
        /// <param name="info">扫描信息</param>
        /// <returns></returns>
        public string HandleEventScancodeWaitmsg(RequestEventScancodeWaitmsg info, AccountInfo accountInfo)
        {
            string result = "";
            try
            {
                var handler = AutoFactory.Instatnce.Container.Resolve<IQRCodeHandler>();
                if (handler != null)
                {
                    result = handler.HandleScancodeWaitmsg(info, accountInfo);
                }
            }
            catch(Exception ex)
            {
                LogHelper.Error(ex);
            }
            return result;
        }

对此中之一的接口处理,我们还得将其分拆,根据扫描的轩然大波键值Key进行不同的音信对应。

        /// <summary>
        /// 扫描后,会等待事件处理结果返回给用户
        /// </summary>
        public string HandleScancodeWaitmsg(RequestEventScancodeWaitmsg info, AccountInfo accountInfo)
        {
            ResponseText response = new ResponseText(info);
            response.Content = string.Format("您的信息为:{0},可以结合后台进行数据查询。", info.ScanCodeInfo.ScanResult);
            var result = response.ToXml();

            string devicecode = GetParam(info.ScanCodeInfo, "devicecode");//参数名为小写
            if (!string.IsNullOrEmpty(devicecode))
            {
                switch(info.EventKey.ToLower())
                {
                    case "device_view"://设备查看
                        {
                            var deviceinfo = BLLFactory<Device>.Instance.FindByCode(devicecode);
                            response.Content = ConvertDeviceInfo(deviceinfo);
                            result = response.ToXml();
                        }
                        break;

                    case "measure"://设备计量
                        {
                            var deviceinfo = BLLFactory<Device>.Instance.FindByCode(devicecode);
                            response.Content = ConvertMeasure(deviceinfo);
                            result = response.ToXml();
                        }
                        break;

                    case "repair"://设备报修,返回报修单号
                        {
                            var content = ConvertRepaire(info, accountInfo, devicecode);
                            response.Content = content;
                            result = response.ToXml();
                        }
                        break;

                    case "inventory"://设备盘点,转到盘点界面
                        {
                            var content = ConvertInventory(info, accountInfo, devicecode);
                            response.Content = content;
                            result = response.ToXml();
                        }
                        break;

                    case "maintain":
                        break;

                    case "check":
                        break;
                    case "device_add":
                        break;
                }
            }

            return result;
        }

以上就是关于下Autofac实现有健康接口处理的贯彻,这种控制反转之不二法门,可以一本万利我们项目的开销效率,可以依据需要指定一些一定的落实拍卖即可,而且通过部署文件之主意加载,可以生便利的开展布置。

 

5.UML图

冲第4节省被之笔触,我们这边被出同种植栅格图层的筹划方式:

 图片 8

6.针对栅格图层设计之详解

从UML图中得以视,我们第一提炼出了各国种瓦片图层所共有的一个基类,即BaseLayer,在这个基类中包括了做每一样种图层所必须有几乎单属性,例如瓦片图层的实质-Canvas,以及各国一个瓦片图层的几哪里边境范围还有针对地图事件之监听和移除方法等。

要具备瓦片图层涉及到之主导算法,即取得瓦片的行号、瓦片在屏幕被的坐标等全是第一以延续于BaseLayer中的ImageLayer里进行定义跟有联合算法的编。其中getMapByGeoExtent是骨干之算法,此算法的功效是用限量外之瓦的url进行折算以及由此url进行瓦片请求和加载。

各级一个切实可行的瓦图层类都是一直接轨给ImageLayer,然后以切实瓦片图层中实现对瓦片行列号的折算,以及瓦片的URL的折算。在地图加载事件触发后,进行execTileRequest方法就调用基类父类ImageLayer中的geoMapByExtent方法。

7.优化栅格图层的统筹

 根据栅格图层设计之法则,可以当少独面展开优化。一个凡是瓦片请求时,请求的地形图范围之优化;一个凡是针对要得到的瓦片按照一定的条条框框缓存到内存中。

7.1瓦请求范围的优化

要是地图每次只请屏幕范围外之瓦片,那么在地图平移被硌就会见展开瓦片请求,这样见面叫前者经常处于瓦片请求状态。但是同,瓦片请求的限制吗不能够过那个,过大会造成请求瓦片时用户等时成为正比。所以,在屏幕范围外装一个客观之缓存范围,使每次要时请的地形图范围也屏幕范围加上缓存范围之与。(screenBoundary+toleranceBoundary)是特别必要之。

7.2瓦片的缓存

要是每次要的瓦都待由服务器或者浏览器的瓦缓存中获,这必将以延伸前端地图的变现时间,如果能够直接以瓦片缓存到外存中,然后遇到相同瓦片时直从外存中读取,这比上述两栽办法都要尽早,能加快前端地图的显得。但是同,瓦片不可知缓存太多,这样针对性内存来说负荷太死,并且多瓦片用过相同赖后,可能后来异常丰富日子还无见面就此到,所以待用自然的调度规则及成立之外存容器大小来放置和治本瓦片。

8.优化的实现

8.1呼吁范围优化的兑现

于实际项目被,有的种类是默认在屏幕范围所对应的瓦范围及,另外当方圆扩充一个或多独瓦片的增长率范围。而有种类,对之不举行其他处理,因为我们实际获得的瓦片范围,其自己就是是超出屏幕所对应的地理范围的。

对想人为扩充一个要么多个瓦片宽度范围的读者,可以于准系列第三节中,计算瓦片实际起始号时,人为的以瓦片起始号进行更改。在改瓦片起始号后,后面计算出来的要瓦片的实际上地理范围等参数都需要作出有关调整。

本来,最简易的是休人也开此优化,因为只要己者所说,我们通过公式算出来的瓦范围本身就是于屏幕地理范围要大的。优化在主导算法中便已经实现了。

8.2瓦片缓存机制的实现

咱们得定义一个大大小小固定的器皿,其中内容是由此键值对来囤积。每个瓦片的URL是绝无仅有的,可以当作Key。而容器中瓦片的调度规则吧下效率排序加先进先出原则。详细流程如下:

(1)容器被新长的瓦片放在有瓦片的面,Max(index)。

(2)容器中为调用的瓦重新在有瓦片的地方(Max(index)),而其他瓦片都自动向前进同各类(index-1)

(3)当容器装满时,将最低层的瓦片删除,即index为0的瓦被删。

9.总结

因之前章节的学问,我们以这无异于章节里从未多描述栅格数据的得到原理与方式,而是把重大都居了栅格图层的设计方面,在终极咱们介绍了有限独优化栅格图层设计之思绪。栅格图层作为WebGIS中地形图的展示核心,设计一个吓的栅格图层组织办法是任重而道远的,否则会照成地形图展示了款,或者未可知十分好之支撑多地形图来源。并且使计划之无成立,会照成大量的代码冗余,导致其他扩大或者保安全会死不便。当然,这里为起之这种规划框架肯定不是绝好的,希望自己能够吃读者抛砖迎玉。下一样回开,要起来接二连三几个章来讲学矢量图层的筹划了。我会从矢量图层的多寡出自、坐标转换与尾声之统筹实现来跟大家齐声完善的追究WebGIS中的矢量图层。欢迎大家持续关注。

                                                                       
             
——欢迎转载,但保留版权,请让大庭广众处于标明出处:http://www.cnblogs.com/naaoveGIS

 

 

万一我们依依不舍,或者感到遗憾,都是为咱们害怕被我们依依不舍的遗憾之物,不见面还经历。

倘经验是得经汗水创造的。我们如果开的免是错开怕,而是去创造。

相关文章

No Comments, Be The First!
近期评论
    分类目录
    功能
    网站地图xml地图