I am trying to extend the Catalog
domain, specifically to add a new string field called CatalogType
to it. I am following the example documented here: Extensibility - Extending domain models - Virto Commerce Documentation but seem to have run into a roadblock.
A new database migration gets created successfully, and I see the new column on the Catalog
table. When I go to the swagger docs, I see my new field show up on the schema.
However, when I call the GET /api/catalog/catalogs/{id}
endpoint, the new field is not returned on the response object. And, when I POST to the /api/catalog/catalogs
endpoint, and include a value for my new field in the body, the value for this field is not saved to the database.
I suspect that Iāve missed something in my Module.cs
file, but am not sure where I went wrong.At the bottom of the example, it mentions There is a technical task of an instantiation of the right āeffectiveā type instance from incoming JSON data (deserialization)......... Use platform-defined PolymorphJsonConverter . It's preferable to use in most cases. The PolymorphJsonConverter transparently deserializes extended domain types with no developer effort.
I read this as ādo nothingā, but perhaps there is some code to be writen.
I have defined a new subclass derived from the original Catalog
class
using VirtoCatalog = VirtoCommerce.CatalogModule.Core.Model.Catalog;
namespace DomainExtension.Catalog.Core.Models
{
/// <summary>
/// Custom extension of the existing Catalog object
/// </summary>
public class Catalog2: VirtoCatalog
{
/// <summary>
/// type of catalog
/// </summary>
public string CatalogType { get; set; }
}
}
I have derived my dbContext from the existing CatalogDbContext
public class DomainExtensionCatalogDbContext : CatalogDbContext
{
public DbSet<Catalog2Entity> Catalog2s { get; set; }
public DomainExtensionCatalogDbContext(DbContextOptions<DomainExtensionCatalogDbContext> options)
: base(options)
{
}
protected DomainExtensionCatalogDbContext(DbContextOptions options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Catalog2Entity>();
base.OnModelCreating(modelBuilder);
}
}
I have derived my repository class from the existing CatalogRepositoryImpl
public class Catalog2Repository: CatalogRepositoryImpl
{
/// <summary>
/// default constructor
/// </summary>
/// <param name="dbContext">extended db context</param>
public Catalog2Repository(DomainExtensionCatalogDbContext dbContext): base(dbContext)
{
}
public IQueryable<Catalog2Entity> Catalogs2 => DbContext.Set<Catalog2Entity>();
}
I have created the new persistence model
public class Catalog2Entity: CatalogEntity
{
/// <summary>
/// property for the type of catalog
/// </summary>
[StringLength(128)]
public string CatalogType { get; set; }
public override VirtoCatalog ToModel(VirtoCatalog catalog)
{
if (catalog is Catalog2 catalog2)
{
catalog2.CatalogType = CatalogType;
}
base.ToModel(catalog);
return catalog;
}
public override CatalogEntity FromModel(VirtoCatalog catalog, PrimaryKeyResolvingMap pkMap)
{
if(catalog is Catalog2 catalog2)
{
CatalogType = catalog2.CatalogType;
}
base.FromModel(catalog, pkMap);
return this;
}
public override void Patch(CatalogEntity target)
{
if(target is Catalog2Entity target2)
{
target2.CatalogType = CatalogType;
}
base.Patch(target);
}
}
In the Module.cs
file Iāve added the following for overriding types in the PostInitialize
method
AbstractTypeFactory<CatalogEntity>.OverrideType<CatalogEntity, Catalog2Entity>();
AbstractTypeFactory<VirtoCatalog>.OverrideType<VirtoCatalog, Catalog2>().WithFactory(() => new Catalog2());
And in the Initialize
method Iāve included
serviceCollection.AddTransient<ICatalogRepository, Catalog2Repository>();
My question is: Where did I go wrong? What am I missing so that I may use the existing API endpoints and have them recognize my extended catalog type.
Thank you in advance!