zoukankan      html  css  js  c++  java
  • 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})

  • 相关阅读:
    leetcode108 Convert Sorted Array to Binary Search Tree
    leetcode98 Validate Binary Search Tree
    leetcode103 Binary Tree Zigzag Level Order Traversal
    leetcode116 Populating Next Right Pointers in Each Node
    Python全栈之路Day15
    Python全栈之路Day11
    集群监控
    Python全栈之路Day10
    自动部署反向代理、web、nfs
    5.Scss的插值
  • 原文地址:https://www.cnblogs.com/lichen861/p/5306568.html
Copyright © 2011-2022 走看看