您好,我一直在遵循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"
}
有人可以帮忙吗!
答案 0 :(得分:2)
我也在尝试从PluralSight教程课程创建NopCommerce 4.10插件,并遇到相同的错误。为我解决的是包含一个PluginDbStartup.cs
文件。以Nop.Plugin.Pickup.PickupInStore
和Nop.Plugin.Shipping.FixedByWeightByTotal
插件为例,他们已经为4.10正确实现了。
我的插件实现可在https://github.com/florianock/NopCommerce_PromoSlider
上获得