文章目录
概述
NopCommerce源码架构详解-教你写一个简单的NopCommerce插件2。
内容
上一篇文章写了要开发一个NopCommerce插件的基本准备工作。现在我们就来看看要让插件正常的显示到页面上还要需要做哪些呢?
1、检查mvc版本
首先要检查之前我们创建的项目nop].Plugin.Widgets.HelloWorld引用的MVC版本是否和Nop.Web的一致,如果更高或更低就要使用nuget安装相应的版本。我用的这个Nop源码在Nop.Web中使用的MVC版本是5.2.0,因此在我们的插件项目也要使用MVC的版本为5.2.0,不然最终调用插件时,运行的时候会报错的。
2、同理也要添加相应版本的Autofac和其它dll的引用,如下图,请依次对照检查。

上面的引用可一个都不能少哦。
3、添加项目所需要文件夹和文件
添加好引用之后,我们就可以放心添加文件夹和类文件了。如下图:

这是一个Nop插件规范的文件结构。Controllers、Models、Views这三个文件夹我想我不用说它们的作用,你懂得^_^。Infrastructure下面有一个DependencyRegistrar类它是用来做依赖注入了。这个类可以从其它插件中拷过来,做一些修改:
using Autofac; using Autofac.Core; using Nop.Core.Caching; using Nop.Core.Infrastructure; using Nop.Core.Infrastructure.DependencyManagement; using Nop.Plugin.Widgets.HelloWorld.Controllers; namespace Nop.Plugin.Widgets.HelloWorld.Infrastructure { public class DependencyRegistrar : IDependencyRegistrar { public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder) { //we cache presentation models between requests //builder.RegisterType<WidgetsHelloWorldController>() // .WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static")); } public int Order { get { return 2; } } } }
本例比较简单,还用不上高大上的依赖注入,所以把这个类的Register方法代码先注释掉。同样的Models下面的两个model分别是ConfigurationModel和PublicInfoModel也先不用管。因为本例先不用model传值到视图,就输出一段固定的html。
注意:打起精神来,下面可是这个插件的重头戏了。
WidgetsHelloWorldController.cs:
using System.Web.Mvc; using Nop.Core; using Nop.Core.Caching; using Nop.Plugin.Widgets.HelloWorld.Infrastructure.Cache; using Nop.Plugin.Widgets.HelloWorld.Models; using Nop.Services.Configuration; using Nop.Services.Media; using Nop.Services.Stores; using Nop.Web.Framework.Controllers; namespace Nop.Plugin.Widgets.HelloWorld.Controllers { public class WidgetsHelloWorldController : BasePluginController { public WidgetsHelloWorldController() { } [AdminAuthorize] [ChildActionOnly] public ActionResult Configure() { return View("~/Plugins/Widgets.HelloWorld/Views/WidgetsHelloWorld/Configure.cshtml"); } [HttpPost] [AdminAuthorize] [ChildActionOnly] public ActionResult Configure(ConfigurationModel model) { return Configure(); } [ChildActionOnly] public ActionResult PublicInfo(string widgetZone, object additionalData = null) { return View("~/Plugins/Widgets.HelloWorld/Views/WidgetsHelloWorld/PublicInfo.cshtml",null); } } }
上面是控制器,也是提供给Nop调用的控制器,并返回相应的内容。我们可以看到上面有两个Action方法。Configure是插件配置用的,PublicInfo是用来前台显示用的。注意:这两个Action最后返回视图都是通过视图的全路径,不然到时是找不到视图文件的。 接下来来添加视图文件。
Configure.cshtml:
@{ Layout = ""; } @model Nop.Plugin.Widgets.HelloWorld.Models.ConfigurationModel @using Nop.Web.Framework; @using (Html.BeginForm()) { <table class="adminContent"> <tr> <td colspan="2"> <input type="submit" name="save" class="k-button" value="@T("Admin.Common.Save")" /> </td> </tr> </table> }
这里配置视图是随便写的,因为暂时还用不上。
PublicInfo.cshtml:
@model Nop.Plugin.Widgets.HelloWorld.Models.PublicInfoModel @{ Layout = ""; } @using System @using Nop.Web.Framework.UI <div class="con" style="font-weight:bold; color:red;"> <ul> <li>HelloWorld</li> <li>HelloWorld</li> <li>HelloWorld</li> <li>HelloWorld</li> <li>HelloWorld</li> <li>HelloWorld</li> <li>HelloWorld</li> <li>HelloWorld</li> <li>HelloWorld</li> <li>HelloWorld</li> </ul> </div>
从上面的视图PublicInfo就可以看到我们这个插件是输出由div、ul、li 组成的几行HelloWorld,非常之简单。
然后,添加一个插件的核心类HelloWorldPlugin.cs,这个类要实现接口IWidgetPlugin和继承类BasePlugin。
HelloWorldPlugin.cs:
using System.Collections.Generic; using System.IO; using System.Web.Routing; using Nop.Core; using Nop.Core.Plugins; using Nop.Services.Cms; using Nop.Services.Configuration; using Nop.Services.Localization; using Nop.Services.Media; namespace Nop.Plugin.Widgets.HelloWorld { /// <summary> /// PLugin /// </summary> public class HelloWorldPlugin : BasePlugin, IWidgetPlugin { public HelloWorldPlugin() { } /// <summary> /// Gets widget zones where this widget should be rendered /// </summary> /// <returns>Widget zones</returns> public IList<string> GetWidgetZones() { return new List<string>() { "home_page_helloworld" }; } /// <summary> /// Gets a route for provider configuration /// </summary> /// <param name="actionName">Action name</param> /// <param name="controllerName">Controller name</param> /// <param name="routeValues">Route values</param> public void GetConfigurationRoute(out string actionName, out string controllerName, out RouteValueDictionary routeValues) { actionName = "Configure"; controllerName = "WidgetsHelloWorld"; routeValues = new RouteValueDictionary() { { "Namespaces", "Nop.Plugin.Widgets.HelloWorld.Controllers" }, { "area", null } }; } /// <summary> /// Gets a route for displaying widget /// </summary> /// <param name="widgetZone">Widget zone where it's displayed</param> /// <param name="actionName">Action name</param> /// <param name="controllerName">Controller name</param> /// <param name="routeValues">Route values</param> public void GetDisplayWidgetRoute(string widgetZone, out string actionName, out string controllerName, out RouteValueDictionary routeValues) { actionName = "PublicInfo"; controllerName = "WidgetsHelloWorld"; routeValues = new RouteValueDictionary() { {"Namespaces", "Nop.Plugin.Widgets.HelloWorld.Controllers"}, {"area", null}, {"widgetZone", widgetZone} }; } /// <summary> /// Install plugin /// </summary> public override void Install() { base.Install(); } /// <summary> /// Uninstall plugin /// </summary> public override void Uninstall() { base.Uninstall(); } } }
这个HelloWorldPlugin类定义了插件调用的名字为home_page_helloworld,通过GetWidgetZones属性调用,以及配置GetConfigurationRoute和前台显示GetDisplayWidgetRoute时的路由信息(Controller和Action相关)。除此之外还有插件的安装Install和卸载Uninstall操作。这里的插件安装和卸载直接调用的基类的方法,当然你也可以在里面写些你个性化的东西。
4、Web.Config配置
这一步也很关键,我就是之前没有注意这点,导致运行一直报下面的报错。这个问题还真浪费了朕一点点时间。^_^
当前上下文中不存在名称“model”

后来找了原因,因为我当初创建的是一个类库项目,是插件项目中只有一个app.config,没有Web.config。于是我从项目Nop.Plugin.Widgets.NivoSlider中把它的Web.config拷过来,重新生成运行就没有问题。Web.config里面的pageBaseType很关键,如下图:

5、安装插件并启用
在Nop后台安装插件并启用我们的插件。点击安装Intall插件之后会在\App_Data下面的InstalledPlugins.txt里面多上一行是我们的插件信息。你可以打开InstalledPlugins.txt检查一下。

安装插件成功后,还要记得启用我们的插件哦,不然Nop是不会显示未被启用的插件的。

6、调用插件
我们把这个HelloWorld插件显示在前台的首页上,看看效果。找到Nop.Web项目下的Views\Home\Index.cshtml,加上代码:@Html.Widget(home_page_helloworld)

最后页面显示的效果如下:

至此,一个很简单的NopCommerce插件就大功告成了。此时此刻,我相信你对Nop的插件开发有了一定的了解了,下次我会讲解一个复杂的例子,开发一个友情链接的Nop插件,可以在后台动态的添加数据。