Proposal of a modified nopCommerce architecture to extend entities

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
9 years ago
Calvince wrote:
how would I add a new property "public string UNSPSC { get; set;}" to the category class?


This change allows you to extend the entities without modifying the core files, but you still have to do the changes in the nop projects:
1- Create a partial class in Nop.Core. I put all changes in a separate folder, so they are easier to identify, like MyProject/Domain/Category.myproject.cs (note the namespace has to be the same than the original class)

public partial class Category
{
   public string UNSPSC { get; set;}
}

2.- Create a partial class in Nop.Data for the mapping, like MyProject/Mapping/Category.myproject.cs

public partial class CategoryMap
{
   protected override void PostInitialize()
   {
       Property(c=>c.UNSPCS).IsOptional().HasMaxLength(400);  // or whatever mapping you need
   }
}

I hope this helps.
9 years ago
This looks really good.

One question though is it possible to extend an entity through a plugin or must it be done in the core touching the Domain Entitiy (Nop.Core/Domain/...) and the Domain Entity Map (Nop.Data/Mapping/...)

The plugin we have developed can mostly be written outside of touching the core products by the use of extending \ overriding the services and using action filters to change the UI pages to include additional model properties.

The plugin designed allows for additional fee's (ie. startup fee's for recurring products). We have used the option of adding an item to the cart for the setup fee however this gets ugly as the customer experience looks as if they can remove the setup fee from the cart (although we intercept it and stop the removal).

What we want to do is from a plugin perspective add two properties to the Order entity of AdditionalFee (inc\ex tax).

Is this possible?
9 years ago
namespace Nop.Web.Framework.Validators
{
  public abstract class NopAbstractValidator<T> : AbstractValidator<T> where T : class
  {
    protected NopAbstractValidator()
    {
      PostInitialize();
    }
  
    protected virtual void PostInitialize() { }
  }
}
9 years ago
nvanhaaster wrote:
One question though is it possible to extend an entity through a plugin or must it be done in the core touching the Domain Entitiy (Nop.Core/Domain/...) and the Domain Entity Map (Nop.Data/Mapping/...)


It has to be done in the core projects. This is a "limitation" of the C# compiler: partial classes are just a compiler trick to let you organize your code better, but the compiled result is still a single class and you cannot have a class split in two different assemblies.

Maybe you could do what you propose putting your extra fields in an independent table. Nop core wouldn't know about it, but your plugin could locate the data there by order Id.
9 years ago
fcastells wrote:

It has to be done in the core projects. This is a "limitation" of the C# compiler: partial classes are just a compiler trick to let you organize your code better, but the compiled result is still a single class and you cannot have a class split in two different assemblies.


Figured that was the case.... Thank you for your insight
9 years ago
fcastells wrote:

It has to be done in the core projects. This is a "limitation" of the C# compiler: partial classes are just a compiler trick to let you organize your code better, but the compiled result is still a single class and you cannot have a class split in two different assemblies.


Figured that was the case.... Thank you for your insight
9 years ago
I have this strange behaviour when I create a partial for an existing Domain class. When I add the following class:

namespace Nop.Data.Mapping.Catalog
{
    public partial class ProductAttributeCombination  
    {
        public virtual string StorageLocation { get; set; }
    }
}

once compiled, the class ProductAttributeCombinationMap in nop.data loses all notions of the original partial ProductAttributeCombination . It only knows about the property 'StorageLocation '. The one that I added.


error CS1061: 'Nop.Data.Mapping.Catalog.ProductAttributeCombination' does not contain a definition for 'Id' and no extension method 'Id' accepting a first argument of type 'Nop.Data.Mapping.Catalog.ProductAttributeCombination' could be found (are you missing a using directive or an assembly reference?)

So it seems that the new partial ProductAttributeCombination  actually overrules the original partial ProductAttributeCombination  as if it doesn't exist...
9 years ago
Is your partial class in the same project and same namespace than the original? If one of these two conditions is not true, your partial class will effectively be a different class, even if it has the same name and the "partial" keyword. The map class will then only see one of them and see only its properties.
9 years ago
Yes indeed.

My class has the same leven of protection, is not abstract, is in the same namespace and is part of the Nop.Core library


When I copy my partial class definition into the same file as the original partial class like below, then it works:

namespace Nop.Data.Mapping.Catalog
{
    public partial class ProductAttributeCombination : BaseEntity
    {
        public int ProductId { get; set; }
        ...
    }


    public partial class ProductAttributeCombination  
    {
        public virtual string StorageLocation { get; set; }
    }
}

but as soon as I move my partial class to its own file it loses the concept of the original class

namespace Nop.Data.Mapping.Catalog
{
    public partial class ProductAttributeCombination  
    {
        public virtual string StorageLocation { get; set; }
    }
}

It's weird...
9 years ago
I think your implementation might be incorrect.
For your mapping (Data) extension, you don't want your get; set; there...that is for your domain (core).
So when I look at your namespace (Nop.Data.Mapping.Whatever)...as your in the mapping / data project you should have something like the following;

namespace Nop.Data.Mapping.Affiliates
{
    public partial class AffiliateMap
    {
        protected override void PostInitialize()
        {
            Property(c => c.ERPSalesCodeId).IsOptional().HasMaxLength(50);
        }
    }
}

The code you presently have displaying should be in a class under the core project(domain) project.

namespace Nop.Core.Domain.Affiliates
{
    /// <summary>
    /// Represents an affiliate
    /// </summary>
    public partial class Affiliate
    {
        public string ERPSalesCodeId { get; set; }
    }
}

Finally, you have "virtual" included... which is to allow for overrides...but I don't think its appropriate here.  So change your 2 class files to be like above (Change Affiliate for the Category namespace, and the my variable for yours), and then you should be set.

Thanks
Chuck
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.