I am working on importing the data from file system provider into Sitecore using Data Exchange framework.While adding the content using regular template in sitecore, the items are imported fine.But I wanted to use Branch template to create the item in the sitecore.I can not create item based on branch template because while debugging the code I have encountered in to source code provided in the Adding Subitems with the Data Exchange Framework answer and according to which, it checks only for template item and not branch item.

The suggested answer in the above thread which says to "override the ItemRepository and implement a new method that caters for Branch Template" but it does not explain how to do it.

I have tried so far, Overriding the item creation using all HttpBegin request pipelines and all item events like item:creating,Item:saving and Item:adding but no solution seem to overwrite the Itemrepository method.

Also, The Add method in Sitecore.Services.Infrastructure.Sitecore.Data.ItemRepository can not be overwritten from anywhere in pipelines.

2 Answers 2

  1. Override InProcItemModelRepository class.
  2. Create patch file to override item model repository.

Have look at Sitecore.DataExchange.Local.config

There is configuration to specify item model repository.

        <tenantRepository type="Sitecore.DataExchange.Repositories.Tenants.SitecoreTenantRepository, Sitecore.DataExchange">
            <itemModelRepository ref="dataExchange/itemModelRepository" />
        <itemModelRepository type="Sitecore.DataExchange.Local.Repositories.InProcItemModelRepository, Sitecore.DataExchange.Local">
        <logger type="Sitecore.DataExchange.Local.Loggers.PrefixedSitecoreLogger, Sitecore.DataExchange.Local">
            <prefix>Data Exchange</prefix>
        <pipelineBatchLoggerService type="Sitecore.DataExchange.Local.Loggers.PipelineBatchLoggerService, Sitecore.DataExchange.Local" />

I didn't see an Add method in the InProcItemModelRepository when overriding the class mentioned above (overriding Add is mentioned in the linked question). I overrode the CreateItem method to have the default code with a few checks marked with comments as custom code as follows:

namespace Common.CustomSitecore.DataExchange.Repositories
    public class CustomInProcItemModelRepository : Sitecore.DataExchange.Local.Repositories.InProcItemModelRepository
        protected override Guid CreateItem(ItemModel itemModel)
            if (itemModel == null || !itemModel.ContainsKey("ParentID"))
                return Guid.Empty;
            var result1 = Guid.Empty;
            var obj1 = itemModel["ParentID"];
            if (!Guid.TryParse(obj1?.ToString(), out result1) || result1 == Guid.Empty)
                return Guid.Empty;
            var obj2 = itemModel["TemplateID"];
            Guid result2;
            if (!Guid.TryParse(obj2?.ToString(), out result2) || result2 == Guid.Empty)
                return Guid.Empty;
            itemModel["TemplateID"] = (object)result2.ToString();
            if (string.IsNullOrWhiteSpace((string)itemModel["ItemName"]))
                return Guid.Empty;
            var itemModel1 = Get(result1, (string)null, 0);
            if (itemModel1 == null)
                return Guid.Empty;
            string empty = string.Empty;
            if (itemModel.ContainsKey("ItemLanguage") && itemModel["ItemLanguage"] != null)
                empty = itemModel["ItemLanguage"].ToString();

            var createdItemModel = this.CreateItemModelWithStringFieldValues(itemModel);

            //custom check to get the template to add's template. We will later check if 
            //this is a normal template or a branch template
            Guid templateOrBranchId;
            ItemModel templateOrBranch = null;
            if (Guid.TryParse(createdItemModel?["TemplateID"]?.ToString(), out templateOrBranchId))
                templateOrBranch = Get(templateOrBranchId);

            //if a branch template add via the branch template add and update otherwise do the default
            Guid responseId = Guid.Empty;
            if (createdItemModel != null && templateOrBranch?["TemplateID"]?.ToString() == Sitecore.TemplateIDs.BranchTemplate.Guid.ToString())
                var db = Factory.GetDatabase(DatabaseName);

                Language branchLanguage;
                var validLanguage = Language.TryParse(empty, out branchLanguage);

                var branch = validLanguage ? db.GetItem(new ID(templateOrBranchId), branchLanguage) 
                    : db.GetItem(new ID(templateOrBranchId));

                var parent = validLanguage ? db.GetItem(itemModel1["ItemPath"].ToString(), branchLanguage) 
                    : db.GetItem(itemModel1["ItemPath"].ToString());

                var newItem = parent.Add(createdItemModel["ItemName"].ToString(), (BranchItem)branch);

                if (newItem == null)
                    Log.Error("Could not create item", this);
                    //Assuming branch's main item is $name, otherwise use the first that can be found
                    var mainItem = branch.Children["$name"] ?? branch.Children.FirstOrDefault();
                    if (mainItem == null)
                        Context.Logger.Error($"Could not find a main template in a branch item: {branch.ID}");
                        createdItemModel[ItemModel.TemplateID] = mainItem.TemplateID;
                        Update(newItem.ID.Guid, createdItemModel, newItem.Language.Name, newItem.Version.Number);

                    responseId = newItem.ID.Guid;
                //this part is not custom. It is the default functionality that adds from a template
                responseId = (this.HandlerProvider.GetHandler<CreateItemHandler>().Handle(
                    (HandlerRequest) new CreateItemCommand()
                        Database = this.DatabaseName,
                        ItemModel = createdItemModel,
                        Path = itemModel1["ItemPath"].ToString(),
                        Language = empty
                    }) as CreateItemResponse).ItemId;

            return responseId;

I potentially could have tried to override the default config entry for my instance shown in the following config snippet. Don't make this config change if you are using the code from above (CustomInProcItemModelRepository) as it is not directly related. If using CustomInProcItemModelRepository patch the config mentioned in Vlad's post:

<itemRepository type="Sitecore.PathAnalyzer.Data.SitecoreData.ItemRepository, Sitecore.PathAnalyzer" singleInstance="true">
   <param ref="pathAnalyzer/configuration" desc="configuration"/>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.