收藏 分享(赏)

nopCommerce的源代码结构和架构说明.docx

上传人:HR专家 文档编号:6617336 上传时间:2019-04-18 格式:DOCX 页数:19 大小:176.46KB
下载 相关 举报
nopCommerce的源代码结构和架构说明.docx_第1页
第1页 / 共19页
nopCommerce的源代码结构和架构说明.docx_第2页
第2页 / 共19页
nopCommerce的源代码结构和架构说明.docx_第3页
第3页 / 共19页
nopCommerce的源代码结构和架构说明.docx_第4页
第4页 / 共19页
nopCommerce的源代码结构和架构说明.docx_第5页
第5页 / 共19页
点击查看更多>>
资源描述

1、nopCommerce 的源代码结构和架构编写本文档是为了向程序员说明 nopcommerce 的解决方案结构,亦是程序员开发 nopcommerce 的居家必备良书。首先 nopcommerce 的源代码很容易拿到,它是开源的,所以你可以直接到网上下载。 在你打开 VS 以后项目和文件夹都会完整列出来,我们建议你在看此文档的同时也打开你的 VS 来浏览项目和文件。绝大多数的项目,目录和文件都顾名思义,你可以从名字就大概知道是做什么的。比如Nop.Plugin.Payments.PayPalStandard 这个我都不用看项目代码就能猜到做什么的。LibrariesNop.CoreNop.Co

2、re 项目包含 nopcommerce 的一系列核心类如缓存,事件,辅助类和业务对象 (如订单和客户实体类)LibrariesNop.DataNop.Data 项目包含一系列的数据访问类和方法以从数据库或其他数据媒介读取和保存数据。它也有助于把数据访问逻辑和你的业务对象分离。 nopcommerce 使用 Entity Framework (EF) Code-First 方法,允许你在 nopcommerce 代码中定义实体 (所有的核心实体类都在 Nop.Core 中定义),再让 EF 生成数据库,这就是为什么会叫 Code-First。你接下来可以用 LINQ 来查询对象,它自己会把查询转

3、换为 SQL 语句并在数据库里执行。nopcommerce 拥有牛 B 的 API 让你完全定制持久映射,你可以在这儿和这儿找到Code-First 的资料。LibrariesNop.Services此项目包含一系列的核心服务,业务逻辑,验证,如果有数据的话还有数据的计算方法,也就是传说中的业务访问层(BAL)Plugins 文件夹中的那些项目Plugins 是 VS 的解决方案文件夹,硬盘中它是在你解决方案的根目录下。由于项目在编译时的输入路径是”PresentationNop.WebPluginsGroup.Name”,这样插件的 DLL 会自动地放到 PresentationNop.We

4、bPlugins文件夹中,用来放置已部署插件。这样也能让插件包含静态文件比如CSS 或 JS,就不用在项目之间拷贝这些文件了。PresentationNop.AdminNop.Admin 是一 MVC 项目,如果你还从没用过 ASP.NET MVC,请猛击这儿有更多信息。可能你已经猜到这是表示层中的管理后台,你可以在 PresentationNop.WebAdministration 文件夹中找到它,此项目不能运行。PresentationNop.WebNop.Web 也是一 MVC 项目,前台网店的表示层,这个才是你真正要跑起来的项目,它也是整个应用程序的起始项目。PresentationN

5、op.Web.FrameworkNop.Web.Framework 是一个表示层的类库项目,包括可以让后台和前台使用的一些共用的展示功能。TestNop.Core.TestsNop.Core.Tests 是 Nop.Core 的测试项目TestNop.Data.TestsNop.Data.Tests 是 Nop.Data 的测试项目TestNop.Services.TestsNop.Services.Tests 是 Nop.Services 的测试项目TestNop.TestsNop.Tests 是一个类库,包含其它测试项目中要用的一共有类和辅助方法,此项目不包含任何测试用例扩展现有实体-添加

6、新的属性Updating an existing entity. How to add a new property.扩展现有实体:如何添加一个新的属性?This tutorial covers how to add a property to the Affiliate entity that ships with the nopCommerce source code.本教程将为代理商实体 Affiliate entity 添加一个属性,附带 nopCom 源码。The data model 数据模型Entities will have two classes that are used

7、to map records to a table. The first class defines the properties, fields, and methods consumed by the web application.实体将有两个类用于映射记录表:第一个类定义 affiliate 的属性、字段和方法。File System Location 文件位置: Project RootLibrariesNop.CoreDomainAffiliatesAffiliate.cs Assembly 程序集 : Nop.Core Solution Location 解决方案中的位置 : N

8、op.Core.Domain.Affiliates.Affilate.csThe second class is used to map the properties defined in the class above to their respective SQL columns. The mapping class is also responsible for mapping relationships between different SQL tables.第二个类是将各属性分别映射到对应的 SQL 列,以及映射不同的 SQL 表之间的关系。File System Location

9、: Project RootLibrariesNop.DataMappingAffiliatesAffiliateMap.cs Assembly: Nop.Data Solution Location: Nop.Data.Mapping.Affiliates.AffiliateMap.csAdd the following property to the Affiliate class.为 Affiliate 添加一个属性: 1/ Instance members must be virtual on data table objects like Affiliate.cs/ Virtual

10、is required by data access frameworks so that these frameworks/ can implement more complex features like lazy loading.public virtual string AffiliateWebSite get; set; Add the following code to the constructor of the AffiliateMap class.为 AffiliateMap 添加一个构造函数: 2/ This code maps a column in the databa

11、se to the new property we created above/ This creates a nullable nvarchar with a length of 255 characters in the/ Affiliate SQL tablethis.Property(m = m.AffiliateWebSite).HasMaxLength(255).IsOptional(); Because Im all about results, at this point I would run the code, re-install the database, and ve

12、rify that the column was created appropriately.修改数据库,为 Affiliate 表添加列:AffiliateWebSite ,允许为空, navrchar(255)。 3重新编译程序 4The presentation model 视图模型The presentation model is used to transport information from a controller to the view (read more at Models have another purpose; defining requirements.表示模

13、型用于传输控制器的信息视图(参考 configured our database to only store 255 characters for the AffiliateWebSite. If we try and save an AffiliateWebSite with 300 characters the application will break (or truncate the text). We want the application to protect users from failures the best we can, and our view models h

14、elp enforce requirements like string length.我们在数据库中设定 AffiliateWebSite 长度为 255 个字符,如果尝试保存 300 个字符的,程序将中断(或截断文本)。因此需要通过程序强制用户输入不超过 255 个字符,尽可能地降低出错。File System Location: Project RootPresentationNop.WebAdministrationModelsAffiliatesAffiliateModel.cs Assembly: Nop.Admin Solution Location: Nop.Admin.Mod

15、els.Affiliates.AffiliateModel.csThe validator class is used to validate the data stored inside of the model class (e.g. required fields, max length, and required ranges).验证输入格式File System Location: Project RootPresentationNop.WebAdministrationValidatorsAffiliatesAffiliateValidator.cs Assembly: Nop.A

16、dmin Solution Location: Nop.Admin.Validators.Affiliates.AffiliateValidator.csAdd the property to our view model.添加视图模型需要的属性: 5/ The NopResourceDisplayName provides the “key“ used during localization/ Keep an eye out for more about localization in future blogsNopResourceDisplayName(“Admin.Affiliates.

17、Fields.AffiliateWebSite“)public string AffiliateWebSite get; set; The requirements code will be added in the constructor of the validator./I think this code can speak for itselfRuleFor(m = m.AffiliateWebSite).Length(0, 255);The viewFile System Location: Project RootPresentationNop.WebAdministrationV

18、iewsAffiliates _CreateOrUpdate.cshtml Assembly: Nop.Admin Solution Location: Nop.Admin.Views.Affiliates._CreateOrUpdate.cshtmlViews contain the html for displaying model data. Place this html under the “active“ section.在视图中添加一行: 6Html.NopLabelFor(model = model.AffiliateWebSite):Html.EditorFor(model

19、= model.AffiliateWebSite)Html.ValidationMessageFor(model = model.Active)The controllerIn this case the controller is responsible for mapping the domain data model to our view model and vice versa. The reason I choose the affiliate model to update is because of the simplicity. I want this to be an in

20、troduction to the nopCommerce platform and I would like to keep it as simple as possible.在这种情况下,控制器负责域数据模型映射到视图模型,反之亦然。这里之所以选择“代理商”模型来更新是因为他比较简单。以便尽可能简单地为大家介绍如何扩展现有实体属性。File System Location: Project RootPresentationNop.WebAdministrationControllerssAffiliateController.cs Assembly: Nop.Admin Solution

21、Location: Nop.Admin.Controllers.AffiliateController.csWere going to make three updates to the AffiliateController class. Data Model - View Model Create View Model - Data Model Edit View Model - Data ModelNormally I would write tests for the following code and verify that model mapping is working cor

22、rectly, but Ill skip unit testing to keep it simple.我们将要进行三次更新 AffiliateController 类。数据模型 - 视图模型创建视图模型 - 数据模型编辑视图模型 - 数据模型通常情况下,我会写下面的代码测试和验证模型的映射正常工作,但我会跳过单元测试,以保持它的简单。In the method PrepareAffiliateModel add the following code below the model.Active = affiliate.Active:找到 Private void PrepareAffilia

23、teModel 方法,在 model.Active = affiliate.Active 后中添加代码: 7/ Data Model - Ceate/Edit View Modelmodel.AffiliateWebSite = affiliate.AffiliateWebSite;In the public ActionResult Create(AffiliateModel model, bool continueEditing) method add the following code below affiliate.Active = model.Active:找到 public Ac

24、tionResult Create(AffiliateModel model, bool continueEditing)方法,在 affiliate.Active = 8model.Active 后添加代码:/ Create View Model - Data Modelaffiliate.AffiliateWebSite = model.AffiliateWebSite;A similar change is required in public ActionResult Edit(AffiliateModel model, bool continueEditing):最后,在 publi

25、c ActionResult Edit(AffiliateModel model, bool continueEditing)方法中添加以下代码: 9/ Edit View Model - Data Modelaffiliate.AffiliateWebSite = model.AffiliateWebSite;Troubleshooting Recreate the database. Either your own custom SQL script or use the nopCommerce installer. Stop the development web server betw

26、een schema changes. Post a detailed comment on our forums.如何编写 nopCommerce 插件插件(Plug-in,又叫 addin、add-in、addon 或 add-on)是一种电脑程序,通过和应用程序的互动,用来替应用程序增加一些所需要的特定的功能。(Wikipedia)插件用来扩展 nopCommerce 的功能, nopcommcer 有多种类型的插件。比如支付方式中的 paypal,税率供应商,配送计算方式(UPS,USP,Fedex),小部件(live chat 功能)等等。nopCommerce 本身也自带了很多不同

27、的插件。你可以在官网上搜索是否已经有人上传了满足你需要的插件。如果没有,哥这就手把手带你编写一个出来。插件结构,所用文件,所在位置1.你第一件事就是要在解决方案中新建一个“ 类库”项目。最好的办法是把插件都放在解决方案根目录(不过小心不要和 Nop.Web 下边的 plugins 目录搞混了,那儿是放已布置插件的),而且最好把插件也都放在解决方案目录的 plugin 目录中(关于更多解决方案文件夹的信息,请猛击此处)最好以这种方法来命名:”Nop.Plugin.Group.Name”。Group 是你插件的分类(比如支付), Name是你的插件名(比如”AuthorizeNet”),那么 Au

28、thorize.NET 的支付插件就会有这样的名字:Nop.Plugin.Payments.AuthorizeNet。2.一旦建立了插件项目,把输入路径改为”PresentationNop.WebPluginsGroup.Name”,比如 Authorize.NET 支付插件就会有这样的输入路径: “PresentationNop.WebPluginsPayments.AuthorizeNet”。搞定以后,对应的插件 DLL 就会被拷贝到 PresentationNop.WebPlugins 文件夹,nopCommerce 内核会搜索此文件夹。a.在项目菜单,点击属性b.选择生成选项卡c.点击

29、输入路径旁边的浏览按钮选择一个输入目录你要在 debug 和 release 模式下都要做此步骤。3.下一步你就要为你的每一个插件建立一个 Description.txt,此文件包含描述插件的信息。你可以从其它插件目录中拷出来。比如 Authorize.NET 支付插件的 Description.txt 就有如下内容:Group: Payment methodsFriendlyName: Credit CardSystemName: Payments.AuthorizeNetVersion: 1.00SupportedVersions: 2.30Author: nopCommerce team

30、DisplayOrder: 1FileName: Nop.Plugin.Payments.AuthorizeNet.dll其实所有的信息你都能看懂,不过有一些注意事项。SystemName 必须唯一。Version 字段是你插件的版本号,你可以将它设置为你喜欢的任何值。SupportedVersions 可以包含一个由逗号分隔的(确保nopCommerce 当前版本包含在此列表中,否则此插件没戏)支持版本清单。FileName 是用这个格式:Nop.Plugin.Group.Name.dll(是你插件的 assembly 文件名)。要确保此文件的“拷贝到输入目录”属性是“Copy if new

31、er”4.所需的最后一个步骤是创建一个类实现 IPlugin 接口(Nop.Core.Plugins 命名空间)。nopCommerce有 BasePlugin 类已经实现了一些 IPlugin 方法,这样你就不用苦逼地再写一遍。nopCommerce 还提供一些从 IPlugin 派生特定的接口。例如,俺们有“IPaymentMethod”接口,用于创建新的付款插件,它包含了一些特定的用于付款的方法如 ProcessPayment()或 GetAdditionalHandlingFee()。nopCommerce目前有以下特定的插件接口:IExternalAuthenticationMeth

32、od. 用来建立外部认证方法如 Facebook, Twitter, OpenID, etc.IWidgetPlugin. 让你可以创建小部件,小部件在你网站的某些地方出现,如左边的 Live chat 框IExchangeRateProvider. 用于获得货币汇率.IDiscountRequirementRule. 允许你创建新的折扣规则比如”帐单寄到的国家必须是“ISMSProvider. 短信提供商,让你可以在下单时收到短信通知。IPaymentMethod. 用于处理支付流程的插件。IPromotionFeed. 这些插件用于向 Froogle 或 PriceGrabber 提供产品

33、信息IShippingRateComputationMethod这些插件是用于获取可用的配送方法和正确的运费。例如,UPS,UPS,FEDEX 等。ITaxProvider. 税率提供商用于获取税率。处理请求。控制器,模型和视图。现在你可以在 Admin area Configuration Plugins 看到我们的插件了,不过正如你所想,这个杯具的插件啥都不能做,甚至连个配置的界面都没有。现在让我们来创建一个配置页面。我们现在需要做的是创建一个控制器,模型和视图。1. MVC 控制器负责响应对一个 ASP.NET MVC 网站的请求。每个浏览器请求被映射到一个特定的控制器。2. 一个视图包

34、含被发送到浏览器的 HTML 标记和内容。视图是相当于一个 ASP.NET MVC 应用程序的页面。3. 一个 MVC 模型包含视图或控制器以外的所有应用程序逻辑。关于 MVC 模式在这里你可以找到更多的信息。那么,我们可以开工了:创建模型。新插件中加入一个 Models 文件夹,然后按你需要新加入一个模型类。创建视图。在插件项目中新加一个 Views 文件夹,再在里边添加一个 Name文件夹,此处Name是指你的插件名。然后再添加一个 Configure.cshtml 文件。很重要的一点:此视图应该要注明是嵌入资源。创建控制器。在插件项目中新加一个 controller 文件夹,再新加一个控

35、制器类。最好的命名办法是像GroupNameController.cs 这样如 PaymentAuthorizeNetController。再好好地命名一个 action 方法用于配置。哥叫它“Configure” 。准备一个模型类并将其传给这个视图:Nop.Plugin.Group.Name.Views. GroupName.Configure,即那个嵌入视图。比如你在 Authorize.NET 支付插件中的PaymentAuthorizeNetController 实现你就会比较清楚。提示一:从其它插件项目中拷贝 web.config 到你项目里来,这样在做视图的时候有智能感知(老丁:啊

36、?真的么?这和拷文件有什么关系?)。智能感知即微软的自动完成亮点。提示二:搞定以上步骤最简单的办法是直接把其它插件项目拷贝过来,然后文件和文件夹改名。提示三:如果你想限制后台(店主)控制器的一些 action 方法,只用在方法上加AdminAuthorize 属性即可。提示四:接下来要确保所有第三方的程序集引用的“拷贝到本地” 属性设为 false,这样可以减小部署包的大小。比如 Authorize.NET 插件的项目结构会如下图:路由现在我们要为插件注册相应的路由。ASP.NET 路由用于把浏览器发送的请求映射成 MVC 控制器相应的action 方法,接下来的步骤你会读到很多详细关于路由的

37、信息。1. 新建如下文件:RouteProvider.cs,它会向 nopcommerce 告知关于插件路由信息。比如下边的RouteProvider 添加了一个新的路由,可以通过浏览器路径http:/www.yourS 来访问:public partial class RouteProvider : IRouteProviderpublic void RegisterRoutes(RouteCollection routes)routes.MapRoute(“Plugin.Payments.AuthorizeNet.Configure“,“Plugins/PaymentAuthorizeNe

38、t/Configure“,new controller = “PaymentAuthorizeNet“, action = “Configure“ ,new “Nop.Plugin.Payments.AuthorizeNet.Controllers“ );public int Prioritygetreturn 0;2. 一些特写的插件接口(像上边讲的)和“IMiscPlugin”接口有一个方法“GetConfigurationRoute”。它应该向控制器返回一个用于插件后台配置的路由。实现你插件的“GetConfigurationRoute”方法,可以告知nopCommerce 你插件的后台

39、配置路由是什么。如果你插件不需要后台配置,那么此方法将返回 NULL,比如下边这样:public void GetConfigurationRoute(out string actionName,out string controllerName,out RouteValueDictionary routeValues)actionName = “Configure”;controllerName = “PaymentAuthorizeNet”;routeValues = new RouteValueDictionary() “Namespaces”, “Nop.Plugin.Payments

40、.AuthorizeNet.Controllers” , “area”, null ;只要你有这个配置方法,插件安装以后你就能在 Admin Configuration Plugins 找到一个配置链接。处理“安装” 和“卸载”方法这是可选步骤。一些插件需要有一定的安装逻辑,比如插件要添加一些本地资源数据。在你的 IPlugin 实现中(大多数情况下是直接从 BasePlugin 类继承下来),重载以下方法:1. Install:在插件安装时会调用此方法,你可以在此初始化任何设置,添加新的本地资源数据或添加新的数据库表(如果需要的话)2.Uninstall:在卸载插件时会调用此方法。重要说明:

41、如果你重载这些方法,不要隐藏基类的实现。比如重载”Install”的时候要记得调用 base.Install(),Authorize.NET 的 install 方法如下:public override void Install()var settings = new AuthorizeNetPaymentSettings()UseSandbox = true,TransactMode = TransactMode.Authorize,TransactionKey = “123,LoginId = “456;_settingService.SaveSetting(settings);base.

42、Install();提示:已安装的插件列表可以在App_DataInstalledPlugins.txt 找到,这个列表是在安装的时候创建的。升级 nopCommerce 可能会让插件挂掉一些插件可能在新版本的 nopCommerce 中挂掉无法工作。如果在升级后有问题,请删除插件再到nopCommerce 官网看看是否有些版本的插件下载。大部分的插件作者都会把他们的插件升级到新的版本,不过少数插件并不会跟随着一起升级从而不再支持新版本。不过大多数情况下,你可以打开相应的 Description.txt 文件并编辑 SupportedVersions 字段。小结希望此文能让你开始 nopCom

43、merce 的插件之旅并搞个出类拔萃的插件。nopCommerce 常见开发问题汇总以下列出的是程序猿攻城湿在开发 nopCommerce 的时候经常提出的问题。它们也表现出nopCommerce 团队对一些架构的选择。文章说明:文章来源自我的博客,于原文之理解而翻译,并非出版社那种按字词翻译风格。欢迎各位提出意见,也欢迎各位转载不过务必注明本文原址。更多 nopcommerce 的文章请关注 http:/ QQ 群 101675096有哪些要求?NopCommerce 的技术和系统要求可以在这儿找到(英文)程序猿如何向 nopCommerce 项目贡献代码?NopCommerce 代码托管在

44、 codeplex Mercurial 代码库,用户点此访问。借此公共代码库,用户可找到将要发布的修改和以前的设计决策。如果想知道 codeplex Mercurial 对版本树的支持请在这儿和这儿找更多信息。程序猿可以很容易地在我们的扩展页面上传插件和语言包并分享给他人。要上传扩展,请在浏览器中访问我的帐号,选择“Your contributions and extensions”选项卡,然后点击“Upload a new extension”按钮。我如何报告一个缺陷?nopCommerce 使用 Codeplex 作为官方缺陷跟踪系统,如果发现一个缺陷,可通过在Codeplex 创建一个任

45、务来报告给 nopCommerce 团队。程序猿或用户也可以在我们的 Bug Reports 论坛版块发帖子来告知新发现的缺陷。如果你的缺陷已经被记录当然最好,正因为此,验证那些没有被记录的缺陷更为重要(比较拗口)。报告重复的缺陷会分心而且让我们在新的开发和改缺陷上时间更少。nopCommerce 的数据访问层Nop.Data 项目包含一系列的类和函数来读取和写入数据库或是其它数据存储介质。Nop.Data 项目有助于将数据访问的逻辑从你的业务对象中 分离出来。NopCommerce 使用Entity Framework (EF) Code-First,Code-First 允许程序员在源代码

46、中定义实体(所有核心实体都在 Nop.Core 项目中定义),然后使用 EF 来生成基于 C# 类的数据库,这就是为何被称为 Code-First。你可以用 LINQ 来查询你的对象,它会悄悄地把代码转化为 SQL 语句并在数据库执行。 Nopcommerce 有流利的 API 用于完全定制化的持久映射。如果想了解更多Code-First 请访问 这儿和这儿控制反转和依赖注入控制反转和依赖注入是两个密不可分的方法用来分离你应用程序中的依赖性。控制反转Inversion of Control (IoC) 意味着一个对象不会新创建一个对象并依赖着它来完成工作。相反,它们从外部获取它们想要的对象。依

47、赖注入 Dependency Injection (DI) 意味着在没有对象的干预下,一般通过能传入构造参数和一系列属性的框架组件完成。马丁虎老二(Martin Fowler)写过一篇关于依赖注入和控制反转的牛 B 文章,我就不要再抄到这儿了,你可以在这儿找到。NopCommerce 使用 Autofac 类库作为 IOC 容器。只要你写了一个服务和此服务已实现的适当接口,你应该在任何实现了 IDependencyRegistrar 接口(Nop.Core.Infrastructure.DependencyManagement 命名空间).的类里注册它。比如所有 nopCommerce 的核心

48、服务都在 Nop.Web.Framework 类库的 DependencyRegistrar类中已注册。public class DependencyRegistrar : IDependencyRegistrarpublic virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder)builder.Register(c = c.Resolve().Request) .As() .InstancePerHttpRequest(); builder.Register(c = c.Resolve().Response) .As() .InstancePerHttpRequest();你想创建多少依赖注册类都可以。每一个类实现了 IDependencyRegistrar 接口的类都有一个 Order 属性,可以用它来替换一个现有的依赖。要覆盖 nopcommerce 的依赖,设置order 属性为大于 0。Nopcommerce 会对依赖排序,并按顺序运行,数字越大你的对象越迟被注册。我如何注册新的路由(路由?我觉得还是用 routes 比较

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 实用文档 > 说明文书

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报