Ошибка NopCommerce 4.10 при установке плагина - PullRequest
0 голосов
/ 24 октября 2018

Привет, вы прошли курс Pluralsight по NopCommerce, но он предназначен для более старой версии.

Я пытался создать ту же функциональность в 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 голосов
/ 16 марта 2019

Я также пытаюсь создать плагин NopCommerce 4.10 из учебного курса по PluralSight и столкнулся с той же ошибкой.Для меня это решило включить файл PluginDbStartup.cs.Возьмите пример с плагинов Nop.Plugin.Pickup.PickupInStore и Nop.Plugin.Shipping.FixedByWeightByTotal, они правильно реализовали его для 4.10.

Моя реализация плагина доступна на https://github.com/florianock/NopCommerce_PromoSlider

...