安装插件时出现NopCommerce 4.10错误

时间:2018-10-24 07:48:04

标签: c# entity-framework-core autofac nopcommerce nopcommerce-4.1

您好,我一直在遵循NopCommerce的Pluralsight课程,但是它是针对旧版本的。

我一直试图在NopCommerce 4.10中构建相同的功能

当我尝试安装插件时,出现错误:

  

未找到满足所有依赖关系的构造函数。

没有在数据库中创建表。 该错误清楚地表明,这是一个不满足的依赖关系,但这是什么?我如何满足?我有一个对象上下文和2个正在autofac中注册的实体,如果我是对的,那就是我所需要的。这是什么问题?

插件文件:

PromoImageRecord.cs

using Nop.Core;

namespace Nop.Plugin.Widgets.PromoSlider.Domain
{
    public class PromoImageRecord: BaseEntity
    {
        public int PromoImageId { get; set; }
        public virtual int PromoSliderId { get; set; }
        public virtual string Caption { get; set; }
        public virtual string Url { get; set; }
        public virtual string FilePath { get; set; }
        public virtual int DisplayOrder { get; set; }

        public PromoSliderRecord PromoSlider { get; set; }

    }
}

PromoSliderRecord.cs

using Nop.Core;
using System;
using System.Collections.Generic;
using System.Text;

namespace Nop.Plugin.Widgets.PromoSlider.Domain
{
    public class PromoSliderRecord: BaseEntity
    {
        public PromoSliderRecord()
        {
            Images = new List<PromoImageRecord>();
        }


        public int PromoSliderId { get; set; }
        public virtual string PromoSliderName { get; set; }
        public bool IsActive { get; set; }
        public virtual string ZoneName { get; set; }
        public virtual int Interval { get; set; }
        public virtual bool PauseOnHover { get; set; }
        public virtual bool Wrap { get; set; }
        public virtual bool KeyBoard { get; set; }

        public virtual List<PromoImageRecord> Images { get; set; }


    }
}

PromoImageMap.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Nop.Plugin.Widgets.PromoSlider.Domain;
using System.Collections.Generic;
using System.Text;

namespace Nop.Plugin.Widgets.PromoSlider.Data
{
    public class PromoImageMap : IEntityTypeConfiguration<PromoImageRecord>
    {
        public void Configure(EntityTypeBuilder<PromoImageRecord> builder)
        {
            builder.ToTable("Some");
            builder.ToTable("PromoSlider_PromoImages");

            //Map the primary key
            builder.HasKey(m => m.PromoImageId);

            builder.Property(m => m.PromoSliderId);
            builder.Property(m => m.Caption);
            builder.Property(m => m.DisplayOrder);
            builder.Property(m => m.Url);

            builder.HasOne(x => x.PromoSlider).WithMany(x => x.Images).HasForeignKey(x => x.PromoSliderId).IsRequired();
        }
    }
}

PromoSliderMap.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Nop.Plugin.Widgets.PromoSlider.Domain;
using System;
using System.Collections.Generic;
using System.Text;

namespace Nop.Plugin.Widgets.PromoSlider.Data
{
    public class PromoSliderMap : IEntityTypeConfiguration<PromoSliderRecord>
    {
        public PromoSliderMap()
        {

        }

        public void Configure(EntityTypeBuilder<PromoSliderRecord> builder)
        {
            builder.ToTable("PromoSlider_PromoSliders");
            builder.HasKey(x => x.PromoSliderId);

            builder.Property(m => m.PromoSliderName);
            builder.Property(m => m.ZoneName);
            builder.Property(m => m.Interval);
            builder.Property(m => m.KeyBoard);
            builder.Property(m => m.PauseOnHover);
            builder.Property(m => m.Wrap);

        }
    }
}

PromoSliderObjectContext.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Nop.Core;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Nop.Data;

namespace Nop.Plugin.Widgets.PromoSlider.Data
{
    public class PromoSliderObjectContext: DbContext, IDbContext
    {
        // (LocalDb)\MSSQLLocalDB
        public PromoSliderObjectContext(string connString): base(SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connString).Options)
        {

        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new PromoSliderMap());
            modelBuilder.ApplyConfiguration(new PromoImageMap());
            base.OnModelCreating(modelBuilder);
        }

        public string CreateDatabaseInstallationScript()
        {
            return this.Database.GenerateCreateScript();
        }

        public void Install()
        {
            var context = new PromoSliderObjectContext(@"Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=NopCommercePractice11;Integrated Security=True");
            context.Database.EnsureCreated();
        }

        public void UnInstall()
        {
            //this.Database.drop
        }

        DbSet<TEntity> IDbContext.Set<TEntity>()
        {
            return base.Set<TEntity>();
        }

        int IDbContext.SaveChanges()
        {
            throw new NotImplementedException();
        }

        string IDbContext.GenerateCreateScript()
        {
            throw new NotImplementedException();
        }

        IQueryable<TQuery> IDbContext.QueryFromSql<TQuery>(string sql)
        {
            throw new NotImplementedException();
        }

        IQueryable<TEntity> IDbContext.EntityFromSql<TEntity>(string sql, params object[] parameters)
        {
            throw new NotImplementedException();
        }

        int IDbContext.ExecuteSqlCommand(RawSqlString sql, bool doNotEnsureTransaction, int? timeout, params object[] parameters)
        {
            throw new NotImplementedException();
        }

        void IDbContext.Detach<TEntity>(TEntity entity)
        {
            throw new NotImplementedException();
        }
    }
}

PromoSliderDependencyRegistrar.cs

using Autofac;
using Nop.Core.Configuration;
using Nop.Core.Infrastructure;
using Nop.Core.Infrastructure.DependencyManagement;
using System;
using System.Collections.Generic;
using System.Text;
using Nop.Web.Framework.Mvc;
using Nop.Data;
using Nop.Plugin.Widgets.PromoSlider.Domain;
using Nop.Core.Data;
using Autofac.Core;

namespace Nop.Plugin.Widgets.PromoSlider.Data
{
    public class PromoSliderDependencyRegistrar : IDependencyRegistrar
    {
        private const string CONTEXT_NAME = "nop_object_context_promo_slider";

        public int Order => 1;

        public void Register(ContainerBuilder builder, ITypeFinder typeFinder, NopConfig config)
        {
            builder.RegisterType<PromoSliderObjectContext>().InstancePerLifetimeScope();

            builder.RegisterType<EfRepository<PromoSliderRecord>>()
                .As<IRepository<PromoSliderRecord>>()
                .WithParameter(ResolvedParameter.ForNamed<IDbContext>(CONTEXT_NAME))
                .InstancePerLifetimeScope();
            builder.RegisterType<EfRepository<PromoImageRecord>>()
                .As<IRepository<PromoImageRecord>>()
                .WithParameter(ResolvedParameter.ForNamed<IDbContext>(CONTEXT_NAME))
                .InstancePerLifetimeScope();
        }
    }
}

PromoSliderPlugin.cs

using Nop.Core.Plugins;
using Nop.Plugin.Widgets.PromoSlider.Data;
using Nop.Services.Cms;
using System;
using System.Collections.Generic;
using System.Text;

namespace Nop.Plugin.Widgets.PromoSlider
{
    public class PromoSliderPlugin: BasePlugin, IWidgetPlugin
    {
        private PromoSliderObjectContext _context;

        public PromoSliderPlugin(PromoSliderObjectContext contenxt)
        {
            _context = contenxt;
        }

        public string GetWidgetViewComponentName(string widgetZone)
        {
            return "WidgetsPromoSlider";
        }

        public IList<string> GetWidgetZones()
        {
            throw new NotImplementedException();
        }

        public override void Install()
        {
            _context.Install();
            base.Install();
        }

        public override void Uninstall()
        {
            _context.UnInstall();
            base.Uninstall();
        }
    }
}

Notes.txt:-

Important points when developing plugins


- All views (cshtml files) and web.config file should have "Build action" set to "Content" and "Copy to output directory" set to "Copy if newer"

- When you develop a new plugin from scratch, and when a new class library is added to the solution, open its .csproj file (a main project file) in any text editor and replace its content with the following one

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework> 
  </PropertyGroup>  
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <OutputPath>..\..\Presentation\Nop.Web\Plugins\Nop.Plugin.Widgets.PromoSlider</OutputPath>
    <OutDir>$(OutputPath)</OutDir>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <OutputPath>..\..\Presentation\Nop.Web\Plugins\Nop.Plugin.Widgets.PromoSlider</OutputPath>
    <OutDir>$(OutputPath)</OutDir>
  </PropertyGroup>
  <!-- This target execute after "Build" target -->
  <Target Name="NopTarget" AfterTargets="Build">
    <!-- Delete unnecessary libraries from plugins path -->
    <MSBuild Projects="$(MSBuildProjectDirectory)\..\..\Build\ClearPluginAssemblies.proj" Properties="PluginPath=$(MSBuildProjectDirectory)\$(OutDir)" Targets="NopClear" />
  </Target>
</Project>

Replace “PLUGIN_OUTPUT_DIRECTORY” in the code above with your real plugin output directory name. 

It’s not required. But this way we can use a new ASP.NET approach to add third-party references. It was introduced in .NET Core. Furthermore, references from already referenced libraries will be loaded automatically. It’s very convenient

plugin.json:-

{
  "Group": "Widgets",
  "FriendlyName": "Promo Slider",
  "SystemName": "Widgets.PromoSlider",
  "Version": "1.0",
  "SupportedVersions": [ "4.10" ],
  "Author": "Any",
  "DisplayOrder": 1,
  "FileName": "Nop.Plugin.Widgets.PromoSlider.dll",
  "Description": "This plugin allows you to change the contents of main page slider"
}

有人可以帮忙吗!

1 个答案:

答案 0 :(得分:2)

我也在尝试从PluralSight教程课程创建NopCommerce 4.10插件,并遇到相同的错误。为我解决的是包含一个PluginDbStartup.cs文件。以Nop.Plugin.Pickup.PickupInStoreNop.Plugin.Shipping.FixedByWeightByTotal插件为例,他们已经为4.10正确实现了。

我的插件实现可在https://github.com/florianock/NopCommerce_PromoSlider

上获得