---
title: "Implement a custom product entity"
slug: "implement-a-custom-product-entity"
abstract: ""
---
# Implement a custom product entity

When deciding whether to add a field to the main product template and corresponding object or whether to add it to a subitem, ask yourself whether the field applies to all products. 

To extend the main product entities: 

1. Create a custom template that inherits from the default product template (*/sitecore/templates/CommerceConnect/Products/Product*) and extends it with further fields.
2. Create a custom product class that inherits from the default `Sitecore.Commerce.Entities.Products.Product` class and extends it with further properties.
3. Create a custom `ProductRepository` class that inherits from the default `Sitecore.Commerce.Data.Products.ProductRepository` class.
4. Override the following two methods to save and load the extended properties. Call the base implementation of these methods:
    - `protected override void UpdateEntityItem(Item entityItem, Product entity)`
    - `protected override void PopulateEntity(Item entityItem, Product entity)`
5. To update the `ProductRepository` element in the `Sitecore.Commerce.Product.config` file:
    - Replace the value of the attribute type with the full type name of the custom product repository class. See the following snippet with the type value in italics.
    - Replace the template ID set in the subelement template. See the following snippet with the template value in italics.

    ```xml
    <productRepository type="Sitecore.Commerce.Data.Products.ProductRepository, Sitecore.Commerce" singleInstance="true">

    <template>{47D1A39E-3B4B-4428-A9F8-B446256C9581}</template>
    ```

    - In the `IncludeTemplates` section, update the GUID of the `ProductTemplateID`.

        For more information, see [Product Index](https://doc.sitecore.com/xp/en/developers/103/sitecore-experience-commerce/indexing.html "Indexing").

    - In the `Commerce.Entities` section of the `Sitecore.CommerceProduct.config` file, update the type attribute of the Product entity entry:

        ```xml
        <commerce.Entities>

        <Product type="Sitecore.Commerce.Entities.Products.Product, Sitecore.Commerce" />
        ```

    - In the `ExcludeTemplates` section of the `Sitecore.Commerce.Products.LuceneDefaultIndexConfiguration.config` file, update the GUID of the ProductTemplateID.

        For more information, see [Default Index](https://doc.sitecore.com/xp/en/developers/103/sitecore-experience-commerce/indexing.html "Indexing").

    - If two-way synchronizing is used, create a custom `ResolveProductChanges` class that inherits from the default `Sitecore.Commerce.Pipelines.Products.SynchronizeProductEntity.ResolveProductChanges` class.

New properties that refer to items in related repositories, such as `Manufacturers`, load a collection of the given type and populate the values. Some internal helper methods, such as `PopulateEntityFieldCollections`, are provided. The following is an example of how the `Manufacturers` collection is populated while loading the product entity.

```csharp
entity.Manufacturers = this.PopulateEntityFieldCollections(
entityItem,
"Manufacturer",
typeof(Manufacturer),
new Dictionary<string, string> { { "ExternalId", "ExternalID" }, { "Name", "Name" }, { "Description", "Description" } })
.Cast<Manufacturer>().ToList();

The actual manufacturer type should be created by calling the Create method on the type Sitecore.Commerce.Entities.EntityFactory, but this is left out to simplify the example.
The PopulateEntityFieldCollections method has the following signature:

/// <summary>
/// Fills the entity collections.
/// </summary>
/// <param name="entityItem">The entity item.</param>
/// <param name="fieldName">Name of the field.</param>
/// <param name="collectionMemberType">Type of the collection member.</param>
/// <param name="properties">The properties.</param>
/// <returns>
/// The collection of the product entities.
/// </returns>

private IEnumerable<ProductEntity> PopulateEntityFieldCollections(Item entityItem, string fieldName, Type collectionMemberType, IDictionary<string, string> properties)

```

Follow the same procedure for other product entities.