Views: 5859
Number of votes: 5
Average rating:

Moving away from ICatalogSystem, part 0

I’m no fan of ICatalogSystem. Since the first day when I used it three years ago, I’ve always confused myself of which methods to use (Remember the confusing CatalogEntryResponseGroup?). The worst part was most of method returning CatalogEntryDto/CatalogNodeDto …, which is not a really nice way to access the property we need. Well, somebody might find love with ICatalogSystem, but definitely not me.

Then EPiServer Commerce 7.5 comes to rescue. Thanks to CatalogContentProvider, we now can use a new, better way, to work with Catalog content, with the way CMS guys have been doing since EPiServer 7.

This blog spot is intended to guide Commerce developer who is familiar with ICatalogSystem (you’re likely to move from Commerce R3 or prior release to 7.5. This is supposed to be a first part of a series, which I hopefully can finish!

Why will you love the content way

Firstly, this is the way being used in CMS. Working on a unified API:s allow you to increase the code- recognition. Once you’re familiar with the API:s, it’ll be much quicker for you to know what the intention the code are doing to do (code-read), and much unlikely for you to use wrong method (code-write). Let’s see an example:

As I mentioned above, the ability to work with Catalog entities in a content way is provided by CatalogContentProvider, but you’ll hardly need to work with it directly. Instead, you’ll work with repository pattern, provided via IContentRepository. If you’re going to work with catalog content, it should be one of your dependencies, but I’m using the Service locator here, for the simplicity.

var contentRepo = ServiceLocator.Instance.Get<IContentRepository>();

That’s it. Now let’s try to get an entry, given the catalog entry Id, edit it name, and then save it back:

With ICatalogSystem, it will likely be this:

var entry = CatalogContext.Current.GetCatalogEntryDto(1, new Mediachase.Commerce.Catalog.Managers.CatalogEntryResponseGroup(Mediachase.Commerce.Catalog.Managers.CatalogEntryResponseGroup.ResponseGroup.CatalogEntryFull);

entry.CatalogEntry[0].Name = entry.CatalogEntry[0].Name + "edited"; CatalogContext.Current.SaveCatalogEntry(entry);



While you can write in content way:

var contentRepo = ServiceLocator.Current.GetInstance<IContentRepository>();

var referenceConverter = ServiceLocator.Current.GetInstance<ReferenceConverter>();

var variantContent = contentRepo.Get<MyVariationContent>(referenceConverter.GetContentLink(1, CatalogContentType.CatalogEntry, 0));

variantContent.Name = variantContent.Name + "edited";

contentRepo.Save(variantContent, DataAccess.SaveAction.Publish);



You might feel not “convinced” in the content way. Wait. Just try to edit a metafield. You’ll see that there’s no easy way to do it with CatalogEntryDto. Instead, you’ll need to use Entry (Damn!) to access the ItemAttributes property. Think went fine until you find out that there’s no way to save an Entry, you’ll need to manipulate MetaObject instead.

And you’re screaming …

While with the content way, all you need to do is a little change of above code:

If you did not define property for your metafield:

variantContent.Property["Something"] = new PropertyString("Hello world");



and if you defined the property (which we recommend to do), you can use the strongly typed property instead:

variantContent.Something = new PropertyString("Hello world");



And it’s done. Yay!

The convenient code is not only reason to go for content way. CMS also have better caching implementation than the one go with eCF, especially for remote cache (in a load-balancing configuration, for example). You can have performance benefits over eCF caching.

The third and the last one is that content way comes with strongly typed type. You can avoid calling wrong metafield name, as C# compiler will check it for you. Instead of entry.ItemAttributes[“SomeVeryLongMetaFeild”] as decimal , you now can use entry.SomeVeryLongMetaField directly. Notice the typo I had with the old way?

Getting familiar with ReferenceConverter

If you want to work with catalog content, you’ll need to know this guy. Seriously. He’s the bridge between eCF catalog and the content system. You might already know it – Catalogs, nodes and entries are stored in separated tables, with an IDENTITY column as the ID. So a catalog id value can also be an entry Id value, and so on. Content system requires that every content needs to have a unique ContentReference, and it’s up to ReferenceConverter to do the hard work.

ReferenceConverter can work two ways, i.e. from catalog entry id to ContentReference, and from ContentReference back to content type and object Id.

Take a look at the method signatures and you’ll be able to get it up and running in matter of minute.

ContentReference GetContentLink(int objectId, CatalogContentType contentType, int versionId)

ContentReference GetContentLink(int contentId, int versionId)

int GetObjectId(ContentReference contentLink)

CatalogContentType GetContentType(ContentReference contentLink)

ContentReference GetContentLink(string code)



Just one thing to note with ReferenceConverter is beware of method with take the entry/node code and returns a ContentReference. Unlike the other methods, which only work in memory, which are very fast, this one need to connect to database to get the id before converting it into ContentReference. Nothing wrong with it, but if performance is your concern, then you should minimize using this. This is one of drawback of ReferenceConverter and until EPiServer introduce some nicer way to map between a code and an id of catalog content, we’ll have to live with it.

I hope this will give you some excitement about the content way when working with catalog content. In next posts, I’ll try to cover up how to move away from ICatalogSystem to IContentRepository. Stay tuned with the updates!

Dec 08, 2015

toni
(By toni, 10/6/2014 8:13:34 PM)

Interesting read, thanks Quan Mai!

Johan Book
(By Johan Book, 10/7/2014 1:36:05 AM)

Great post, thanks Quan! I think readability could be further improved if a code style was used on the code snippets! Thanks.

Quan Mai
(By Quan Mai, 10/7/2014 3:25:46 AM)

Thank you. I had trouble figuring out how to use code style in Live Writer - I guess our blog system is not the best out there - will try next time!

K Khan
(By K Khan , 12/8/2015 5:50:36 PM)

Your commerce experience speaking in this blog. It will be great help, if you could cover languages and markets related scenarios also as part of this series. Great Post, I am looking forward for other posts on this topic.

Regards
/K

Vincent Yang
(By Vincent Yang, 12/9/2015 2:43:43 AM)

I am a bit curious when episerver did stop non ecd member posting a comment? I have to switch account to say thank you for your sharing :)

Madis Vellamäe
(By Madis Vellamäe, 3/17/2016 11:40:40 AM)

Nice post! But what about if I needed to find entries based on some metafield value? For example, old web store system was using it's own database ID's in product links and for SEO we need to find the product based on that ID. I believe using the ICatalogSystem is the only way. Please correct me if I'm wrong and there is some new functionality I'm not aware of!

Please login to comment.