Привет, вы прошли курс 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"
}
Может кто-нибудь помочь, пожалуйста!