• NopCommerce带数据访问的插件开发


    NopCommerce带数据访问的插件开发

    一.插件结构,所需的文件和位置

    1.首先在项目解决方案中新建一个类库,类库放在项目根目录Plugins文件夹下。

    插件项目推荐的命名方式”Nop.Plugin.{Group}.{Name}”,{Group}是你的插件分组名称,{Name}是你的插件名称。例如:Nop.Plugin.Payments.PayPalStandard。这也不是必须的,你可以自己选择任何名称来命名你的插件。

     

    2.当插件项目建立完成后,你需要修改项目的输出路径。设置成"....PresentationNop.WebPlugins{Group}.{Name}"

     

    1. 在项目菜单中,点击属性.
    2. 选择”生成”选项卡。
    3. 修改输出路径。

    3.下一步创建一个Description.txt文件,这是每个插件必须的文件。它包含插件的描述元数据。你可以从别的插件项目中复制一个过来,然后修改一下。

    Group: Payment methods

    FriendlyName: Credit Card

    SystemName: Payments.AuthorizeNet

    Version: 1.00

    SupportedVersions: 2.30

    Author: nopCommerce team

    DisplayOrder: 1

    FileName: Nop.Plugin.Payments.AuthorizeNet.dll

    SystemName字段必须是唯一的,Version是插件的版本号,SupportedVersions是支持的nopcommerce版本号,FileName是插件的程序集文件名称,确保“复制到输出目录”属性设置为“复制如果更新”。

    二.创建一个带数据访问的插件

    1.创建一个新的类库项目”Nop.Plugin.Other.ProductViewTracker”.

     

    2.添加相关的文件夹和description.txt文件。

     

    3.description.txt你可以参考下面的图片

     

    4.添加相关引用并设置它们的复制本地为False

    • Nop.Core.dll
    • Nop.Data.dll
    • Nop.Services.dll
    • Nop.Web.Framework.dll
    • EntityFramework.dll
    • System.Data.Entity.dll
    • System.Web.dll
    • System.Web.Mvc.dll
    • Autofac.dll
    • Autofac.Integration.Mvc.dll

    5.在domain命名空间下建立一个公共类 TrackingRecord,继承BaseEntity.注意一点,所有的属性都是virtual,virtual属性为需要对数据库实体的实体框架如何实例化和跟踪类。

     1 using Nop.Core;
     2  namespace Nop.Plugin.Other.ProductViewTracker.Domain
     3 {
     4     public partial class TrackingRecord : BaseEntity
     5     {
     6  
     7         public virtual int ProductId { getset; }
     8       
     9         public virtual string ProductName { getset; }
    10  
    11         public virtual int CustomerId { getset; }
    12  
    13         public virtual string IpAddress { getset; }
    14  
    15         public virtual bool IsRegistered { getset; }
    16  
    17     }
    18 }
    View Code 

    6.下一个类创建的是实体框架映射类。在映射类中,我们映射列、表关系和数据库表。在Data创建TrackingRecordMap类

    using Nop.Data.Mapping;          using Nop.Plugin.Other.ProductViewTracker.Domain;
    
     namespace Nop.Plugin.Other.ProductViewTracker.Data
    
    {
    
        public partial class TrackingRecordMap : NopEntityTypeConfiguration<TrackingRecord>
    
        {
    
            public TrackingRecordMap()
    
            {
    
                this.ToTable("ProductViewTracking");
    
                this.HasKey(x => x.Id);    
    
                this.Property(x => x.ProductId);  
    
                this.Property(m => m.ProductName).HasMaxLength(400);
    
                this.Property(m => m.IpAddress);
    
                this.Property(m => m.CustomerId);
    
                this.Property(m => m.IsRegistered);
    
            }
    
        }
    
    }
    View Code

    7.下一个类是数据访问层中最复杂和最重要的一个类。实体框架对象上下文是一个通过类的传递给我们的数据库访问,并帮助跟踪实体状态(如添加,更新,删除)。上下文也被用来生成数据库模式或更新现有架构。在自定义上下文类中,我们不能引用以前存在的实体,因为这些类型已经关联到另一个对象上下文中。

    这也就是为什么我们在跟踪记录中没有复杂的关系属性。

    using Nop.Core;using Nop.Data;using System.Data.Entity;using System.Data.Entity.Infrastructure;using System;
    
     namespace Nop.Plugin.Other.ProductViewTracker.Data
    
    {
    
        public class TrackingRecordObjectContext :DbContext,IDbContext
    
        {
    
            public bool ProxyCreationEnabled
    
            {
    
                get
    
                {
    
                    throw new NotImplementedException();
    
                }
    
     
    
                set
    
                {
    
                    throw new NotImplementedException();
    
                }
    
            }
    
     
    
            public bool AutoDetectChangesEnabled
    
            {
    
                get
    
                {
    
                    throw new NotImplementedException();
    
                }
    
     
    
                set
    
                {
    
                    throw new NotImplementedException();
    
                }
    
            }
    
     
    
            public TrackingRecordObjectContext(string nameOrConnectionString) : base(nameOrConnectionString) { }
    
     
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
            {
    
                modelBuilder.Configurations.Add(new TrackingRecordMap());
    
                base.OnModelCreating(modelBuilder);
    
            }
    
     
    
            public string CreateDatabaseInstallationScript()
    
            {
    
                return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript();
    
            }
    
     
    
            public void Install()
    
            {
    
                //It's required to set initializer to null (for SQL Server Compact).
    
                //otherwise, you'll get something like "The model backing the 'your context name' context has changed since the database was created. Consider using Code First Migrations to update the database"
    
                Database.SetInitializer<TrackingRecordObjectContext>(null);
    
     
    
                Database.ExecuteSqlCommand(CreateDatabaseInstallationScript());
    
                SaveChanges();
    
            }
    
     
    
            public void Uninstall()
    
            {
    
                var dbScript = "DROP TABLE ProductViewTracking";
    
                Database.ExecuteSqlCommand(dbScript);
    
                SaveChanges();
    
            }
    
     
    
            public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
    
            {
    
                return base.Set<TEntity>();
    
            }
    
     
    
            public System.Collections.Generic.IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : BaseEntity, new()
    
            {
    
                throw new System.NotImplementedException();
    
            }
    
     
    
            public System.Collections.Generic.IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters)
    
            {
    
                throw new System.NotImplementedException();
    
            }
    
     
    
            public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters)
    
            {
    
                throw new System.NotImplementedException();
    
            }
    
     
    
            public void Detach(object entity)
    
            {
    
                throw new NotImplementedException();
    
            }
    
        }
    
    }
    View Code

     

    8.服务层连接数据访问层和表现层,该服务层将数据层与业务逻辑层包裹,并且表示层依赖于服务层。因为我们的任务很小,我们的服务层只是与仓库沟通(在nopCommerce行为库facade对象上下文)。

     接口服务:

    using Nop.Core;using Nop.Plugin.Other.ProductViewTracker.Domain;
    
     namespace Nop.Plugin.Other.ProductViewTracker.Services
    
    {
    
        public partial interface IViewTrackingService
    
        {
    
            /// <summary>
    
            /// Logs the specified record.
    
            /// </summary>
    
            /// <param name="record">The record.</param>
    
            void Log(TrackingRecord record);
    
        }
    
    }
    View Code

    服务:

    using Nop.Core.Data;
    using Nop.Plugin.Other.ProductViewTracker.Domain;
    
     namespace Nop.Plugin.Other.ProductViewTracker.Services
    
    {
    
        public partial class ViewTrackingService : IViewTrackingService
    
        {
    
            private readonly IRepository<TrackingRecord> _trackingRecordRepository;
    
     
    
            public ViewTrackingService(IRepository<TrackingRecord> trackingRecordRepository)
    
            {
    
                _trackingRecordRepository = trackingRecordRepository;
    
     
    
            }
    
     
    
            /// <summary>
    
            /// 记录指定的记录
    
            /// </summary>
    
            /// <param name="record">记录</param>
    
            public void Log(TrackingRecord record)
    
            {
    
                _trackingRecordRepository.Insert(record);
    
            }
    
        }
    
    }
    View Code

     

    9.依赖注入,新建DependcyRegisterar.cs

    using Autofac;
    using Autofac.Core;
    using Nop.Core.Configuration;
    using Nop.Core.Data;
    using Nop.Core.Infrastructure;
    using Nop.Core.Infrastructure.DependencyManagement;
    using Nop.Data;
    using Nop.Plugin.Other.ProductViewTracker.Data;
    using Nop.Plugin.Other.ProductViewTracker.Domain;
    using Nop.Plugin.Other.ProductViewTracker.Services;
    using Nop.Web.Framework.Mvc;
    
     namespace Nop.Plugin.Other.ProductViewTracker
    
    {
    
        /// <summary>
    
        /// Dependency registrar
    
        /// </summary>
    
        public class DependencyRegistrar : IDependencyRegistrar
    
        {
    
            private const string CONTEXT_NAME = "nop_object_context_product_view_tracker";
    
            /// <summary>
    
            /// Register services and interfaces
    
            /// </summary>
    
            /// <param name="builder">Container builder</param>
    
            /// <param name="typeFinder">Type finder</param>
    
            /// <param name="config">Config</param>
    
            public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder, NopConfig config)
    
            {
    
                builder.RegisterType<ViewTrackingService>().As<IViewTrackingService>().InstancePerLifetimeScope();
    
     
    
                //data context
    
                this.RegisterPluginDataContext<TrackingRecordObjectContext>(builder, CONTEXT_NAME);
    
     
    
                //override required repository with our custom context
    
                builder.RegisterType<EfRepository<TrackingRecord>>()
    
                    .As<IRepository<TrackingRecord>>()
    
                    .WithParameter(ResolvedParameter.ForNamed<IDbContext>(CONTEXT_NAME))
    
                    .InstancePerLifetimeScope();
    
            }
    
     
    
            /// <summary>
    
            /// Order of this dependency registrar implementation
    
            /// </summary>
    
            public int Order
    
            {
    
                get { return 1; }
    
            }
    
        }
    
    }
    View Code

     

    10.控制器,在Controllers文件夹下添加TrackingController.cs

    using Nop.Core;
    using Nop.Plugin.Other.ProductViewTracker.Domain;
    using Nop.Plugin.Other.ProductViewTracker.Services;
    using Nop.Web.Framework.Controllers;
    using Nop.Services.Catalog;
    using Nop.Core.Plugins;
    using System.Web.Mvc;
    using Nop.Core.Domain.Catalog;
    using Nop.Core.Domain.Customers;
    
     namespace Nop.Plugin.Other.ProductViewTracker.Controllers
    
    {
    
        public class TrackingController : BasePluginController
    
        {
    
            private readonly IProductService _productService;
    
            private readonly IViewTrackingService _viewTrackingService;
    
            private readonly IWorkContext _workContext;
    
     
    
            public TrackingController(IWorkContext workContext,
    
                IViewTrackingService viewTrackingService,
    
                IProductService productService,
    
                IPluginFinder pluginFinder)
    
            {
    
                _workContext = workContext;
    
                _viewTrackingService = viewTrackingService;
    
                _productService = productService;
    
            }
    
     
    
            [ChildActionOnly]
    
            public ActionResult Index(int productId)
    
            {
    
                //Read from the product service
    
                Product productById = _productService.GetProductById(productId);
    
     
    
                //If the product exists we will log it
    
                if (productById != null)
    
                {
    
                    //Setup the product to save
    
                    var record = new TrackingRecord();
    
                    record.ProductId = productId;
    
                    record.ProductName = productById.Name;
    
                    record.CustomerId = _workContext.CurrentCustomer.Id;
    
                    record.IpAddress = _workContext.CurrentCustomer.LastIpAddress;
    
                    record.IsRegistered = _workContext.CurrentCustomer.IsRegistered();
    
     
    
                    //Map the values we're interested in to our new entity
    
                    _viewTrackingService.Log(record);
    
                }
    
     
    
                //Return the view, it doesn't need a model
    
                return Content("");
    
            }
    
        }
    
    }
    View Code

     

    11.路由,添加RouteProvider.cs

    using System.Web.Mvc;
    using System.Web.Routing;
    using Nop.Web.Framework.Mvc.Routes;
    
     namespace Nop.Plugin.Shipping.ByWeight
    
    {
    
        public partial class RouteProvider : IRouteProvider
    
        {
    
            public void RegisterRoutes(RouteCollection routes)
    
            {
    
                
    
                routes.MapRoute("Plugin.Other.ProductViewTracker.Log",
    
                    "tracking/productviews/{productId}",
    
                     new { controller = "Tracking", action = "Index" }
    
                );
    
            }
    
            public int Priority
    
            {
    
                get
    
                {
    
                    return 0;
    
                }
    
            }
    
        }
    
    }
    View Code

     

    12.插件安装程序 ,添加ProductViewTrackerPlugin.cs

    using Nop.Core.Plugins;
    using Nop.Plugin.Other.ProductViewTracker.Data;
    
     namespace Nop.Plugin.Other.ProductViewTracker
    
    {
    
        public class ProductViewTrackerPlugin:BasePlugin
    
        {
    
            private readonly TrackingRecordObjectContext _context;
    
     
    
            public ProductViewTrackerPlugin(TrackingRecordObjectContext context)
    
            {
    
                _context = context;
    
            }
    
     
    
            public override void Install()
    
            {
    
                _context.Install();
    
                base.Install();
    
            }
    
     
    
         
    
     
    
            public override void Uninstall()
    
            {
    
                _context.Uninstall();
    
                base.Uninstall();
    
            }
    
     
    
     
    
        }
    
    }
    
     
    View Code

    13.使用,跟踪代码应该被添加到producttemplate.simple.cshtmlproducttemplate.grouped.cshtml文件。

    @Html.Action(“Index”,”Tracking”,new {productId=Model.Id})

  • 相关阅读:
    第七节:扩展组件(lodash/富文本/echart/nprogress) 和 帮助类(日期格式化)
    第六节:基础组件(Cascader/Tab/Steps/Upload/TimeLine/alert) 之 参数/商品/订单
    第九节:Vuex简介、基本使用、核心功能(State、Mutation、Action、Getter) 和 案例实战演练
    第四节:基础组件(Breadcrumb、Card、Input、Dialog、Switch、Select、MessageBox) 之 用户管理
    第三节:基础组件(Container布局、NavMenu导航) 之 系统主页面搭建
    第二节:基础配置(路由、less、静态资源、axios、ESLint)、基础组件(Form、Message) 之登录页面搭建
    第七节:框架全面升级5.x版本及常规组件的升级和集成
    第一节:项目初始化(ElementUI、axios)、Git版本管理、基本环境搭建
    第八节:Vue Cli简介/安装、两种Create项目的方式、相关配置说明
    第三节:ES6模块化历史 及 默认、按需、直接导入导出、Vue单文件
  • 原文地址:https://www.cnblogs.com/lichen861/p/5306568.html
Copyright © 2020-2023  润新知