Shannon Gray
Aug 21, 2012
(4 votes)

Generating Typed Business Foundation Classes In EPiCommerce


Business Foundation is a pretty powerful tool... and you'll probably like it more if you make use of what I provide here. We'll be covering code generation and templates to make access and modification of business foundation data much cleaner and clearer.

Business Foundation is an Object Relation Modeling tool built right into EPiCommerce that allows you to very easily store custom data that doesn't fit into the EPiCommerce data model. I've found Business Foundation useful in most implementations because there's almost always custom data that needs to be stored about customer pricing, gift cards, authentication SSO tickets, and a myriad of other things.

For more introduction to using Business Foundation, take a look at this blog from Cecilia von Wachenfelt:

For a more in-depth look at the Business Foundation architecture and API, look here:

The Problem

There are only a few problems I have with using Business Foundation. They're problems that are solvable but the solutions were always manual. Here are the problems I've had with it:

* Business Foundation entities are not typed. This means there were string names for fields everywhere in the code, which is quite error prone and messy. This can be addressed using string constants to make sure they're only defined once.
* Caching is not built into Business Foundation, unlike the catalog, customer, and order subsystems.
* The interface to retrieve Business Foundation entities is too generic. Its powerful by being generic but the code readability is low because of it.
* It provides most of what's needed for paging but its missing a returned record count. When paging is setup, you need to know a) what the first record is needed on a page, b) the number of records to be returned, and c) the total number of records available to paging control (so the number of pages can be calculated). Right now, Business Foundation only allows you to input the first two parameters but doesn't give you a count of the total number of records matching the query.

Here is an example snapshot that shows you what it looks like using the existing Business Foundation objects:


A Solution

McCodeGen.exe is a free tool (I didn't write it) for business foundation code generation that will help solve this (see download link below). I've also provided some templates that can be used by McCodeGen.exe to specifically address these shortcomings. By following the directions below, you can create several typed business foundation classes.

One template is a simple typed Business Foundation class that will generate a class file for an existing Business Foundation class. It inherits from EntityObject and simply exposes the fields for an EntityObject as typed fields. The next two templates can be used to create context classes which provide an API to retrieve, update, create, and delete these typed Business Foundation objects. One of the context class templates provides access to the Business Manager methods used to retrieve EntityObject but returns the typed objects instead. The other context class template has this functionality plus caching and full paging support. The latter context class allows you to configure the cache timeout.

The typed Business Foundation class template is called "EntityObjectSimple.aspx". The non-cached typed Business Foundation context class template is "EntityObjectAccessTemplateNoCaching.aspx". The cached typed Business Foundation context class template is "EntityObjectAccessTemplate.aspx". All of these files are located in the Templates folder of the files in the download link below.

Here's an example of what the above code would look like using generated classes:


Much better right?

There are a few caveats/points to be made about the classes created using these templates:
* Classes generated by the class template will have a property called ExtendedProperties to provide access to any fields that have been added to the business foundation entity definition but not defined in the class (for example, because the class wasn't updated after a field was added).
* Classes generated by the cached context class provides overloads to either a)use a member Boolean property value to determine whether to use the cache or not or b) override the member Boolean indicator with your own specific caching indicator. So you can set a default value for whether records will be cached or retrieved from the cache AND you can override it when needed.
* The cached context class template explicitly defines the cache timeout period. Its very easy to change the template to your desired timeout or use config settings to set them. There are lots of possible enhancements/changes you may need to make here depending on your implementation.
* Both context classes are singletons.
* The record count takes the FilterElements to build a dynamic SQL query and return a count of the number of records matching the List(/Search) conditions. I'm sure there are more elegant solutions and I'm happy to repost (and give credit) if someone wants to improve that... or for that matter, any part of these templates.

Directions For Implementing

1. Unzip download from here: Download Link. Add the following .dlls to the bin directory.
* Mediachase.BusinessFoundation.Data.dll
* Mediachase.BusinessFoundation.Data.XmlSerializers.dll
* Mediachase.BusinessFoundation.ObjectModel.dll
* Mediachase.CodeGen.dll
* Mediachase.CodeGen.VisualStudio.dll
* Mediachase.Ibn.Core.dll
* Mediachase.Ibn.Core.XmlSerializers.dll
* Mediachase.Ibn.Data.dll
* Mediachase.Ibn.Data.Services.dll
* Mediachase.Ibn.Data.XmlSerializers.dll
* Mediachase.Ibn.ObjectModel.dll

2. Copy one of the .mcgen files into the root folder (doesn't matter which one). Rename the .mcgen file so that its clear what Business Foundation class its associated with and the purpose of the class.
3. Open the newly-copied version of the .mcgen file in the root folder. Set the connectionString element value to the connection string for the EPiCommerce database containing the business foundation class definition. Set the MetaClass element value to the name of the Business Foundation class you are typing. In the mcgen element, set the template for the class you want to use, for example "Templates\EntityObjectAccessTemplate.aspx"; see the descriptions of the templates above. In the params definition, set the namespace param value to the namespace you'd like the class to contain, for example "EPiServer.Training.BusinessObjects".
4. Open a commandline to the root folder. Run the following command :
mccodegen -mcgen:<name of .mcgen file created in the root folder in step 2. Include the .mcgen extension> -out:<name of class file to be generated with .cs at the end>

For example: mccodegen -mcgen:GiftCard.mcgen -out:GiftCardAccess.cs

A new class will be created based on the template you specified. You'll need to use the typed class template to generate the typed Business Foundation class; use one of the context class templates to generate the context class to access the typed Business Foundation class.

5. For each typed class or context class you want to create, iterate through steps 2-4.

For further study, there are ways to build the McCodeGen tool into your Visual Studio environment so that you can easily update you typed Business Foundation classes as described here:
I've included files necessary for this in the Visual Studio folder.

Aug 21, 2012


Carl Ribbegårdh
Carl Ribbegårdh Sep 27, 2012 11:07 AM

The DLL's you are referring to, should they have been in the download?

Carl Ribbegårdh
Carl Ribbegårdh Sep 27, 2012 11:44 AM

I've found them all in the Zip file in the Tools folder in in C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\Install\Modules\EPiServer Commerce\MediachaseECF

Thanks a lot for this blog post!

Shella Cabatbat-Rivera
Shella Cabatbat-Rivera Dec 12, 2013 10:10 PM

I noticed that when we define Business Foundation objects via Commerce Manager, the system automatically creates a cls_ table in the database.

Instead of using the BusinessManager, would there be a downside to use a custom ORM framework (e.g. Entity, Linq-to-Sql) against the cls_ tables (aside from initial configuration of classes)?

We need to create complex queries against the BF objects, and, thus, we want to take advantage of strongly-typed objects and relationship navigation properties -- which is built-in on the newer ORM frameworks.

Please login to comment.
Latest blogs
Content Delivery API – The Case of the Duplicate API Refresh Token

Creating a custom refresh provider to resolve the issues with duplicate tokens in the DXC The post Content Delivery API – The Case of the Duplicate...

David Lewis | Sep 29, 2022 | Syndicated blog

New Optimizely certifications - register for beta testing before November 1st

In January 2023, Optimizely is making updates to the current versions of our certification exams to make sure that each exam covers the necessary...

Jamilia Buzurukova | Sep 28, 2022

Optimizely community meetup - Sept 29 (virtual + Melbourne)

Super excited to be presenting this Thursday the 29th of September at the Optimizely community meetup. For the full details and RSVP's see the...

Ynze | Sep 27, 2022 | Syndicated blog

Preview multiple Visitor Groups directly while browsing your Optimizely site

Visitor groups are great - it's an easy way to add personalization towards market segments to your site. But it does come with it's own set of...

Allan Thraen | Sep 26, 2022 | Syndicated blog

The Report Center is finally back in Optimizely CMS 12

With Episerver.CMS.UI 12.12.0 the Report Center is finally re-introduced in the core product.

Tomas Hensrud Gulla | Sep 26, 2022 | Syndicated blog

Dynamic Route in ASP.NET Core When MapDynamicControllerRoute Does Not Work

Background Creating one of the add-on for Optimizely I had to deal with challenge to register dynamically route for the API controller. Dynamic rou...

valdis | Sep 25, 2022 | Syndicated blog