c# - 安装插件时出现 NopCommerce 4.10 错误
问题描述
嗨,一直在关注 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"
}
有人可以帮忙吗!
解决方案
我还尝试从 PluralSight 教程课程中创建一个 NopCommerce 4.10 插件,但遇到了同样的错误。为我解决的问题是包含一个PluginDbStartup.cs
文件。以插件为例Nop.Plugin.Pickup.PickupInStore
,Nop.Plugin.Shipping.FixedByWeightByTotal
他们已经为 4.10 正确实现了它。
我的插件实现可在https://github.com/florianock/NopCommerce_PromoSlider上找到
推荐阅读
- java - 启动 SQLWorkbench/J 时出现“无法加载 Java 运行时环境”
- c++ - C++ CMake 编译指令与?
- rest - Clockify - 将所有数据导入 excel 或使用 REST api 访问的最佳方式?
- javascript - 有没有办法可以在链接标签中引用本地 const 文件
- bootstrap-4 - 为什么引导程序中不存在 bd-navbar
- cmake - cmake_configuration_types 和 3rd 方库
- c# - ORACLE & VS 2005 性能问题
- excel - Excel:条件格式列或整行内的更多(文本)实例
- java - 我在Java中做错了什么?(简单的问题)
- windows - NSIS 安装程序应用程序名称未正确显示