c# - 安装插件时 NopCommerce 4.10 错误

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

您好,一直关注Pluralsight NopCommerce 上的类(class),但它适用于旧版本。

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

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

No constructor was found that had all the dependencies satisfied.

数据库中未创建任何表。 该错误明确指出这些是未满足的依赖项,但它是哪个?我怎样才能满足它?我有一个对象上下文和 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"
}

有人可以帮忙吗?

最佳答案

我还尝试从 PluralSight 教程类(class)创建 NopCommerce 4.10 插件,但遇到了相同的错误。对我来说解决这个问题的是包含一个 PluginDbStartup.cs 文件。以 Nop.Plugin.Pickup.PickupInStoreNop.Plugin.Shipping.FixedByWeightByTotal 插件为例,它们已在 4.10 中正确实现。

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

关于c# - 安装插件时 NopCommerce 4.10 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52963505/

相关文章:

c# - 窗体 : multiple keys pressed

c# - 如何验证表的MAX值?

c# - 如何使用 FromSqlRaw Entity Framework Core 3.1 从存储过程返回多个 SELECT 集

logging - 使用 Common.Logging 和 Autofac 的自动化工厂?

asp.net-mvc - IoC - 在需要时延迟 Controller 中的服务初始化

c# - C# 中的共享点编程

c# - 日期时间中的 fff 和 ms 有什么区别?

c# - 在 EF 中使用枚举类

c# - 如何防止 EF Core 3.1 中的列更新?

asp.net-mvc - EF、ASP MVC + 依赖注入(inject)。多个并发请求和数据库连接的问题