当前位置: 首页 > 编程日记 > 正文

TinyFrame升级之八:实现简易插件化开发

本章主要讲解如何为框架新增插件化开发功能。

在.net 4.0中,我们可以在Application开始之前,通过PreApplicationStartMethod方法加载所需要的任何东西。那么今天我们主要做的工作就集中在这个时间段:

1.将插件DLL及文件拷贝入主网站目录并编译

2.加载Plugin

首先来说说第一步,由于这步里面,我们主要拷贝DLL及文件,所以我们利用了一个List<Assembly>容器来记录所有的插件的DLL,具体代码如下:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Web;
   6:  using System.Reflection;
   7:  using System.Web.Hosting;
   8:  using System.IO;
   9:  using System.Web.Compilation;
  10:  using TinyFrame.Framework;
  11:   
  12:  [assembly: PreApplicationStartMethod(typeof(PluginManager), "Initialize")]
  13:  namespace TinyFrame.Framework
  14:  {
  15:      public class PluginManager
  16:      {
  17:          private const string pluginDirectory = "~/Areas";
  18:          private const string pluginShadowCopyDirectory = "~/Areas/Temp";
  19:          private static readonly List<Assembly> pluginAssemblies=new List<Assembly>();
  20:   
  21:          //初始化方法
  22:          public static void Initialize()
  23:          {
  24:              var pluginPath = HostingEnvironment.MapPath(pluginDirectory);
  25:              //var pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Areas");
  26:              foreach (var file in Directory.EnumerateFiles(pluginPath, "*Plugin*.dll", SearchOption.AllDirectories))
  27:              {
  28:                  pluginAssemblies.Add(Assembly.LoadFile(file));
  29:              }
  30:   
  31:              pluginAssemblies.ForEach(BuildManager.AddReferencedAssembly);
  32:   
  33:              AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
  34:          }
  35:   
  36:          private static Assembly AssemblyResolve(object sender, ResolveEventArgs resolveArgs)
  37:          {
  38:              var currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();
  39:              // 如果未加载程序集
  40:              foreach (var assembly in currentAssemblies)
  41:              {
  42:                  if (assembly.FullName == resolveArgs.Name || assembly.GetName().Name == resolveArgs.Name)
  43:                  {
  44:                      return assembly;
  45:                  }
  46:              }
  47:   
  48:              return null;
  49:          }
  50:   
  51:          //得到程序集名稱
  52:          public static List<string> PluginNames()
  53:          {
  54:              return pluginAssemblies.Select(c => c.GetName().Name).ToList();
  55:          }
  56:      }
  57:  }

第12行,主要标志本方法将于Application_Start开始之前执行。

第17行,主要定义了主网站中放置插件的目录,这里为Areas目录。

第22行,为我们的初始化方法。

第28行,遍历我们的插件目录,加载名称中包含Plugin关键字的DLL。

第31行,遍历完毕后,将这些DLL加入到BuildManager中,以便于编译操作。

这里讲完之后,剩下的就是来写我们的插件了,这里要进行的是第二步:

首先,新建一个TinyFrame.Plugin.NivoSlider的MVC 4 站点,在这个站点根目录下面添加一个名称为AreaRegister.cs的类文件,内容如下:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Web;
   5:  using System.Web.Mvc;
   6:   
   7:  namespace TinyFrame.Plugin.Sample
   8:  {
   9:      public class AreaRegister : AreaRegistration
  10:      {
  11:   
  12:          public override string AreaName
  13:          {
  14:              get
  15:              {
  16:                  return "TinyFrame.Plugin.NivoSlider";
  17:              }
  18:          }
  19:   
  20:          public override void RegisterArea(AreaRegistrationContext context)
  21:          {
  22:              context.MapRoute(
  23:                      "NivoSlider_default",
  24:                      "NivoSlider/{controller}/{action}/{id}",
  25:                      new { action = "Index", id = UrlParameter.Optional },
  26:                      new string[] { "TinyFrame.Plugin.NivoSlider.Controllers" }
  27:                  );
  28:          }
  29:   
  30:      }
  31:  }

其中,类本身需要继承自AreaRegistration,以便于使用MVC本身提供的插件化支持。然后通过重载AreaName和RegisterArea方法,实现AreaName的定义和路由的映射。AreaName主要是为了识别返回的Plugin内容区域,而RegisterArea主要是为路由访问提供了支持。需要注意的是,第26行是Controller的命名空间,需要写上,否则会因为插件的目录和主站的目录一致,导致报错。

然后我们来添加测试的Controller和View:

在Controllers文件夹下面添加NivoSliderController.cs类,并返回一个空的页面:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Web;
   5:  using System.Web.Mvc;
   6:   
   7:  namespace TinyFrame.Plugin.NivoSlider.Controllers
   8:  {
   9:      public class NivoSliderController : Controller
  10:      {
  11:          public ActionResult Index()
  12:          {
  13:              return View();
  14:          }
  15:   
  16:      }
  17:  }

然后在Views文件夹下新建NivoSlider文件夹,并在其中创建一个名称为Index.cshtml的页面文件:

   1:  @{
   2:      ViewBag.Title = "Index";
   3:  }
   4:  <div style="width:600px;height:400px;margin:0 auto;">
   5:    <div class="slider-wrapper theme-default" style="float:left;">
   6:          <div id="slider" class="nivoSlider">
   7:              <img src="@Url.Content("~/Content/slider/images/toystory.jpg")"  alt="" />
   8:              <img src="@Url.Content("~/Content/slider/images/up.jpg")"        alt="" title="This is an example of a caption" />
   9:              <img src="@Url.Content("~/Content/slider/images/walle.jpg")"     alt="" data-transition="slideInLeft" />
  10:              <img src="@Url.Content("~/Content/slider/images/nemo.jpg")"      alt="" title="#htmlcaption" />
  11:          </div>
  12:          <div id="htmlcaption" class="nivo-html-caption">
  13:              <strong>This</strong> is an example of a <em>HTML</em> caption with <a href="#">a link</a>. 
  14:          </div>
  15:      </div>
  16:  </div>
  17:   

这样,我们的页面就准备好了。

QQ截图20140421225046

然后右击这个插件项目,选择属性,在“生成”标签页面,我们需要把输出路径从"bin\"修改成 “..\TinyFrame.Web\Areas\”,这样做是为了将最新的DLL文件拷贝到主站目录中。

之后在”生成事件“标签页面,在”后期生成事件命令行“下的文本框中,输入以下命令,以便于将样式文件等也拷贝到主站的Areas插件目录中:

   1:  xcopy "$(ProjectDir)\Views" "$(TargetDir)\TinyFrame.Plugin.NivoSlider\Views\" /s /i /y
   2:  xcopy "$(ProjectDir)\Areas" "$(TargetDir)\TinyFrame.Plugin.NivoSlider\Areas\" /s /i /y
   3:  xcopy "$(ProjectDir)\Content" "$(TargetDir)\TinyFrame.Plugin.NivoSlider\Content\" /s /i /y

其中,TinyFrame.Plugin.NivoSlider就是你之前定义的AreaName。

这样,当项目编译完毕之后,会自动把DLL文件,视图文件,样式文件等拷贝到主站的Areas插件目录下:

QQ截图20140421225631

最后让我们来配置下主站:

首先在主站的Content目录下添加slider文件夹,并将NivoSlider用到的所有CSS文件,JS文件引入,然后利用ActionLink,来链接至这个幻灯片插件:

   1:  <!DOCTYPE html>
   2:   
   3:  <html>
   4:  <head>
   5:      @RenderSection("featured", false)
   6:      <meta name="viewport" content="width=device-width" />
   7:      <title>书籍借阅系统</title>
   8:      <!--EasyUI CSS files-->
   9:      <link rel="stylesheet" type="text/css" href="@Url.Content("~/Content/jqueryeasyui/themes/default/easyui.css")" />
  10:      <link rel="stylesheet" type="text/css" href="@Url.Content("~/Content/jqueryeasyui/themes/icon.css")" />
  11:   
  12:      <!--BootStrap CSS&JS files-->
  13:      <link href="@Url.Content("~/Content/mycss/default.css")" rel="stylesheet" type="text/css" />
  14:      <link href="@Url.Content("~/Content/bootstrap/css/bootstrap.min.css")" rel="stylesheet" type="text/css" />
  15:      <link href="@Url.Content("~/Content/bootstrap/css/bootstrap-theme.min.css")" rel="stylesheet" type="text/css" />
  16:      <script src="@Url.Content("~/Content/jquery/jquery.min.js")" type="text/javascript"></script>
  17:      <script src="@Url.Content("~/Content/bootstrap/js/bootstrap.min.js")" type="text/javascript"></script>
  18:   
  19:      <!--EasyUI JS files-->
  20:      <script src="@Url.Content("~/Content/jqueryeasyui/jquery.easyui.min.js")" type="text/javascript")"></script>
  21:      <script src="@Url.Content("~/Content/jqueryeasyui/plugins/datagrid-detailview.js")" type="text/javascript")"></script>
  22:      <script src="@Url.Content("~/Content/jqueryeasyui/DataGrid.js")" type="text/javascript"></script>
  23:   
  24:      <!--NivoSlider-->
  25:      <link href="@Url.Content("~/Content/slider/themes/default/default.css")" rel="stylesheet" type="text/css" />
  26:      <link href="@Url.Content("~/Content/slider/nivo-slider.css")" rel="stylesheet" type="text/css" />
  27:      <script src="@Url.Content("~/Content/slider/scripts/jquery.nivo.slider.js")" type="text/javascript"></script>
  28:      <script src="@Url.Content("~/Content/slider/scripts/base.js")" type="text/javascript"></script>
  29:  </head>
  30:  <body>
  31:      <div class="containerMaster">
  32:          <ul class="nav nav-pills" id="menu">
  33:            <li>@Html.ActionLink("书籍入库", "Book", "Home", new { Area = string.Empty }, new { })</li>
  34:            <li>@Html.ActionLink("借入借出", "BookLend", "Home", new { Area = string.Empty }, new { })</li>
  35:            <li>@Html.ActionLink("书籍分类", "BookType", "Home", new { Area = string.Empty }, new { })</li>
  36:            <li>@Html.ActionLink("书籍存放", "BookPlace", "Home", new { Area = string.Empty }, new { })</li>
  37:            <li>@Html.ActionLink("学生管理", "Student", "Home", new { Area = string.Empty }, new { })</li>
  38:            @*<li>@Html.ActionLink("人员管理","Manager","Home")</li>*@
  39:            
<li>@Html.ActionLink("幻灯片插件", "Index", "NivoSlider", new { Area = "TinyFrame.Plugin.NivoSlider" }, new { })</li>
  40:          </ul>
  41:      </div>
  42:      @RenderBody()
  43:  </body>
  44:  </html>

需要注意的是,在上图代码中,着色的部分是访问插件的链接,Area = "TinyFrame.Plugin.NivoSlider"是我们之前定义的AreaName。

运行起来项目,让我们看看结果吧:

QQ截图20140421230153

这节就讲完了,我们用已有的方法实现了一个简易的插件系统,但是,这个插件系统还不完善,做到商用还是远远不够的,缺点有以下几个:

1.无法进行热插拔,插件的更新需要重启网站。

2.无法检测插件的更新。

而下一章节,我们将会打造一个克服以上缺点的强大易用的插件系统。敬请期待。

以下问题及解决方法是我在开发过程中遇到的,在这里我讲答案贴出,以便于记录及追踪:

1).提示无法找到System.Web.Optimization,是否缺少引用?
    解决方法:
      1.PM> Install-Package Microsoft.AspNet.Web.Optimization 或者 
      2.删掉web.config中的引用

2).“找到多个与名为“Home”的控制器匹配的类型。如果为此请求(“{controller}/{action}/{id}”)提供服务的路由在搜索匹配此请求的控制器时没有指定命名空间,则会发生此情况。如果是这样,请通过调用含有“namespaces”参数的“MapRoute”方法的重载来注册此路由。”
解决方法:
出现该问题的愿原因是在默认的Golbal.asax.cs文件中已经注册了默认路由
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
//new string[] { "Working_with_Areas.Controllers"}
);
}
而在AREAS中有注册了一个同名的Controller
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
//new string[] { "Working_with_Areas.Areas.Admin.Controllers" }
);
}
解决方法就是在每个注册Router的时候加上命名空间即可。

3).运行的时候,经常无法出现最新编译好的页面。

调试plugin的时候,请先将 输出路径改成  bin\  等调试完毕后,修改成..\TinyFrame.Web\Areas\,否则你调试的页面一直都是Bin目录下的,而非你设置的..\TinyFrame.Web\Areas\ 目录下的。

2014.04.22更新

1.添加了一个强类型的Plugin插件,用于检测强类型程序集是否能够被编译。

2.插件路由新增了controller参数,用于规避某些特定场合下访问出现404的错误。

 public class AreaRegister : AreaRegistration{public override string AreaName{get{return "TinyFrame.Plugin.NivoSlider";}}public override void RegisterArea(AreaRegistrationContext context){context.MapRoute("NivoSlider_default","NivoSlider/{controller}/{action}/{id}",new { controller = "NivoSlider", action = "Index", id = UrlParameter.Optional },new string[] { "TinyFrame.Plugin.NivoSlider.Controllers" });}}

3.修改了生成事件中的后期生成命令行,由于插件中的Content或者是Scripts中的某些图片或者是文件需要拷贝到主站中,所以这里添加了拷贝到主站目录的方法。

最后,提供源代码下载:

百度网盘链接

微云链接

相关文章:

快手王华彦:端上视觉技术的极致效率及其短视频应用实践 | AI ProCon 2019

演讲嘉宾 | 王华彦&#xff08;快手硅谷Y-tech实验室负责人&#xff09; 编辑 | Just 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 快手用户日均上传1500万个视频&#xff0c;要把这些作品准确的分发给超2亿活跃用户&#xff0c;如果没有强大的AI技术系统去理解…

tmux简介及安装

tmux是一个开源工具&#xff0c;用于在一个终端窗口中运行多个终端会话。它可以减少过多的打开终端控制台。tmux的源码在 https://github.com/tmux/tmux &#xff0c;它的License是BSD。tmux可以直接通过sudo apt-get install tmux命令安装(通过sudo apt-get remove tmux移除)…

Swift中依赖注入的解耦策略

原文地址&#xff1a;Dependency Injection Strategies in Swift 简书地址&#xff1a;Swift中依赖注入的解耦策略 今天我们将深入研究Swift中的依赖注入&#xff0c;这是软件开发中最重要的技术之一&#xff0c;也是许多编程语言中使用频繁的概念。 具体来说&#xff0c;我们将…

Eclipse mac 下的快捷键

2019独角兽企业重金招聘Python工程师标准>>> Eclipse&#xff0c;MyEclipse 的preference 在“windows”下边&#xff0c;mac下在左上角苹果图标边上 win下我们都习惯了ctrl c&#xff0c;在Mac 下使用标准键盘变成了win键c 系统的偏好设定 -> 键盘 -> 修饰…

Ubuntu上使终端显示Git分支(oh-my-zsh)

oh-my-zsh是基于Zsh(Zsh是一个Linux用户很少使用的power-shell&#xff0c;这是由于大多数Linux产品安装&#xff0c;以及默认使用bash shell)的功能作了一个扩展&#xff0c;方便插件管理、主体自定义等。oh-my-zsh源码在 https://github.com/robbyrussell/oh-my-zsh &#x…

天哪!我的十一假期被AI操控了

&#xff08;图片付费下载自视觉中国&#xff09;导语&#xff1a;这个假期&#xff0c;除了脑海一直在唱歌&#xff0c;庆祝祖国成立的 70 周年&#xff0c;当然也闲不住&#xff0c;要乘机出去浪一浪。目前小长假进度条已经进行到 71.4% 了&#xff0c;有没有发现这个假期与以…

使用SVN+Axure RP 8.0创建团队项目

一、使用到的工具&#xff1a;VisualSVN Server --SVN服务器&#xff1a;https://www.visualsvn.com/server/ Axure RP 8.0 &#xff1a;http://www.downcc.com/soft/103078.html 二、VisualSVN Server 安装以及操作1、安装 &#xff1a; 默认安装即可 2、操作&#xff1a; &a…

no no no.不要使用kill -9.

2019独角兽企业重金招聘Python工程师标准>>> no no no.不要使用kill -9. 它没有给进程留下善后的机会&#xff1a; 1) 关闭socket链接 2) 清理临时文件 3) 将自己将要被销毁的消息通知给子进程 4) 重置自己的终止状态 等等。 通常&#xff0c;应该发送15&#xff0c…

人工智能的“天罗地网”

&#xff08;图片付费下载自视觉中国&#xff09;整理 | 弯月编辑 | 郭芮来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;人工智能&#xff08;AI&#xff09;技术正在全球迅速崛起。不断涌现的最新发展令世人瞩目&#xff0c;从以假乱真的深度伪造视频&#xff0c…

Ubuntu下安装Cppcheck源码操作步骤

Cppcheck是用在C、C中对code进行静态检查的工具。它的源码在 https://github.com/danmar/cppcheck 。它的License是GPL-3.0。Cppcheck可以检查不通过编译的文件&#xff0c;执行的检查包括&#xff1a;(1)、自动变量检查&#xff1b;(2)、数组的边界检查&#xff1b;(3)、clas…

用“脸”打卡,抬头就能签到!

科技正在飞速改变我们的生活&#xff0c;以前我们上班的时候&#xff0c;脖子上总会挂一个IC卡用来验证身份和签到打卡&#xff0c;后来指纹识别出现了&#xff0c;我们又逐渐习惯了指纹打卡&#xff0c;到如今&#xff0c;随着人脸识别技术的出现&#xff0c;我们开始用“脸”…

OC基础第四讲--字符串、数组、字典、集合的常用方法

OC基础第四讲--字符串、数组、字典、集合的常用方法 字符串、数组、字典、集合有可变和不可变之分。以字符串为例&#xff0c;不可变字符串本身值不能改变&#xff0c;必须要用相应类型来接收返回值&#xff1b;而可变字符串调用相应地方法后&#xff0c;本身会改变&#xff1b…

分类、检测、分割任务均有SOTA表现,ACNet有多强?

&#xff08;图片付费下载自视觉中国&#xff09;作者 | 路一直都在来源 | 知乎专栏Abstract本文提出了一种新的自适应连接神经网络(ACNet)&#xff0c;从两个方面对传统的卷积神经网络(CNNs)进行了改进。首先&#xff0c;ACNet通过自适应地确定特征节点之间的连接状态&#xf…

CUDA Samples: approximate prior vbox layer

以下CUDA sample是分别用C和CUDA实现的类似prior vbox layer的操作&#xff0c;并对其中使用到的CUDA函数进行了解说&#xff0c;各个文件内容如下&#xff1a;common.hpp:#ifndef FBC_CUDA_TEST_COMMON_HPP_ #define FBC_CUDA_TEST_COMMON_HPP_#include <typeinfo> #inc…

如何成为一名成功的 iOS 程序员?

前言&#xff1a; 编程是一个仅靠兴趣仍不足以抵达成功彼岸的领域。你必须充满激情&#xff0c;并且持之以恒地不断汲取更多有关编程的知识。只是对编程感兴趣还不足以功成名就——众所周知&#xff0c;我们工作起来像疯子。 编程是一个没有极限的职业&#xff0c;所以要成为一…

C#之委托与事件

委托与事件废话一堆&#xff1a;网上关于委托、事件的文章有很多&#xff0c;一千个哈姆雷特就有一千个莎士比亚&#xff0c;以下内容均是本人个人见解。1. 委托1.1 委托的使用这一小章来学习一下怎么简单的使用委托&#xff0c;了解一些基本的知识。这里先看一下其他所要用到的…

24式加速你的Python

作者 | 梁云1991来源 Python与算法之美一、分析代码运行时间第1式&#xff0c;测算代码运行时间平凡方法快捷方法&#xff08;jupyter环境&#xff09;第2式&#xff0c;测算代码多次运行平均时间平凡方法快捷方法&#xff08;jupyter环境&#xff09;第3式&#xff0c;按调用函…

pip、NumPy、Matplotlib在Windows上的安装过程

Windows上Python 3.6.2 64位的安装步骤&#xff1a;1. 从 https://www.python.org/downloads/windows/ 下载Windows x86-64 executable installer(即python-3.6.2-amd64.exe)&#xff1b;2. 直接以管理员身份运行安装&#xff0c;勾选添加到环境变量、pip等即可。可以同时在Wi…

分享:个人是怎么学习新知识的

为什么80%的码农都做不了架构师&#xff1f;>>> 挺多童鞋问我是怎么学习新知识的&#xff0c;干脆写篇文章总结一下&#xff0c;希望对大家有所帮助。对照书、技术博客、极客时间等学习的方式我就不说了。 一、早期 在15年及更早&#xff0c;由于知识储备少&#x…

easyui的datagrid

datagrid数据的绑定方式&#xff1a; 1&#xff09;data 后跟数据行的json串 2&#xff09;url 后跟{"total":,"rows":,"foot":},其中total代码返回总行数&#xff0c;rows为数据行json串 .NET MVC&#xff0c;controll控制类方法中获取datagrid…

线性回归介绍及分别使用最小二乘法和梯度下降法对线性回归C++实现

回归&#xff1a;在这类任务中&#xff0c;计算机程序需要对给定输入预测数值。为了解决这个任务&#xff0c;学习算法需要输出函数f:Rn→R。除了返回结果的形式不一样外&#xff0c;这类问题和分类问题是很像的。这类任务的一个示例是预测投保人的索赔金额(用于设置保险费)&am…

4种最常问的编码算法面试问题,你会吗?

导语&#xff1a;面试是测查和评价人员能力素质的一种考试活动。最常问的编码算法面试问题你知道多少呢&#xff1f;作者 | Rahul Sabnis译者 | 苏本如&#xff0c;编辑 | 刘静来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;在许多采访中&#xff0c;我经常被要求…

[小梅的体验课堂]Microsoft edge canary mac版本体验

简介 华硕微软越来越没有自己的JC了&#xff0c;不经在windows里面加了wsl而且还废弃了自己的老edge浏览器&#xff0c;重新基于chromium内核开发了新的edge浏览器了&#xff0c;不管怎么说mac上又多了一款新的浏览器&#xff0c;对于一个爱好新鲜的我来说那就简单安装体验下 下…

SQL Server用户自定义函数

用户自定义函数不能用于执行一系列改变数据库状态的操作&#xff0c;但它可以像系统 函数一样在查询或存储过程等的程序段中使用&#xff0c;也可以像存储过程一样通过EXECUTE 命令来执行。在 SQL Server 中根据函数返回值形式的不同将用户自 定义函数分为三种类型&#xff1a;…

C++11中std::initializer_list的使用

initializer_list是一种标准库类型&#xff0c;用于表示某种特定类型的值的数组。和vector一样&#xff0c;initializer_list也是一种模板类型&#xff0c;定义initializer_list对象时&#xff0c;必须说明列表中所含元素的类型。和vector不一样的是&#xff0c;initializer_li…

WijmoJS 2019V1正式发布:全新的在线 Demo 系统,助您快速上手,开发无忧

2019独角兽企业重金招聘Python工程师标准>>> 下载WijmoJS 2019 v1 WijmoJS是为企业应用程序开发而推出的一系列包含HTML5和JavaScript的开发控件。其中包含了金融图表、FlexSheet、先进的JavaScript控件&#xff08;Wijmo 5&#xff09;和经典的jQuery小部件&#x…

最后3天,BDTC 2019早鸟票即将售罄,超强阵容及议题抢先曝光!

大会官网&#xff1a;https://t.csdnimg.cn/U1wA2019 年12月5-7 日&#xff0c;由中国计算机学会主办&#xff0c;CCF 大数据专家委员会承办&#xff0c;CSDN、中科天玑数据科技股份有限公司协办的 2019 中国大数据技术大会&#xff0c;将于北京长城饭店隆重举行。届时&#xf…

php_mongo.dll下载(php操作mongoDB需要)

php_mongo.dll下载&#xff08;php操作mongoDB需要&#xff09;如果PHP连接操作mongoDB就必须要加入此扩展&#xff1a;php_mongo.dll&#xff0c;放到你对应php的扩展目录在你的php.ini中加入&#xff1a;extensionphp_mongo.dll重启apache&#xff0c;在phpinfo()中查看是否有…

十大机器智能新型芯片:华为抢占一席,Google占比最多

&#xff08;图片付费下载自视觉中国&#xff09;整理 | 胡巍巍来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;当年&#xff0c;阿基米德爷爷说出“给我一个支点&#xff0c;我就能撬动地球”这句话时&#xff0c;估计没少遭受嘲讽。然而后来的我们&#xff0c;都…

C++/C++11中头文件numeric的使用

<numeric>是C标准程序库中的一个头文件&#xff0c;定义了C STL标准中的基础性的数值算法(均为函数模板)&#xff1a; (1)、accumulate: 以init为初值&#xff0c;对迭代器给出的值序列做累加&#xff0c;返回累加结果值&#xff0c;值类型必须支持””算符。它还有一个…