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})

原文地址:https://www.cnblogs.com/lichen861/p/5306568.html