xConnect: Adding custom facets in Sitecore 9

The default collection model in xDB comes with many of the fields you would normally need for storing information about a visitor, but there are almost always those special cases where you need to store something very specific to your business that doesn’t come out of the box. As with previous versions of xDB, the collection model is very flexible and easy to extend to fit your needs.

As mentioned in an earlier post, not only has the collection model changed a bit, but the way you “deploy” the customizations has also changed.

Adding Custom Facets

In this example, we’re going to be adding a custom facet to the Contact object called SalesRegion. Start by creating a new class library project. I called mine xConnectIntro.Model. Then create a new class called SalesRegion.

[FacetKey(FacetName)]
public class SalesRegion : Facet
{
    public const string FacetName = "SalesRegion";

    public string Region { get; set; }
}

Once you have defined your facet, we need to create a new, referenceable model configuration.

public class xConnectIntroModel
{
    public static XdbModel Model { get; } = BuildModel();

    private static XdbModel BuildModel()
    {
        var builder = new XdbModelBuilder("xConnectIntroModel", new XdbModelVersion(1, 0));
        builder.ReferenceModel(Sitecore.XConnect.Collection.Model.CollectionModel.Model);
        builder.DefineFacet<Contact, SalesRegion>(SalesRegion.FacetName);
        builder.DefineEventType<LeadCaptured>(true);

        return builder.BuildModel();
    }
}

When instantiating the XdbModelBuilder, you provide a new name for your model, in our case, xConnectIntroModel, and provide a version of this model using the XdbModelVersion object. This allows you to version your collection models just like you would any other API.

Then, using the builder.DefineFacet method, define your custom facet, SalesRegion, on the Contact entity. Custom facets can also be defined on the Interaction entity as well. Once your new facet is defined, call the BuildModel() method.

Adding Custom Event Types

Not only can you define new facets on entities, you can define custom event types as well.

Start by creating a new class inheriting from Sitecore.XConnect.Event.

public class LeadCaptured : Event
{
    public string ContactInfo { get; set; }

    public LeadCaptured(Guid definitionId, DateTime timestamp) : base(definitionId, timestamp)
    {

    }
}

Then, using the DefineEventType method to define this event type.

builder.DefineEventType<LeadCaptured>(true);

Deploying Custom Collection Models to xConnect

Now that we have defined our facets and our event types, it’s time to deploy them to xConnect. The first thing we need to do is generate a JSON file for our xConnectIntroModel model configuration. You can do this with a simple Console Application.

class Program
{
    static void Main(string[] args)
    {
        var model = Sitecore.XConnect.Serialization.XdbModelWriter.Serialize(xConnectIntroModel.Model);
        File.WriteAllText(xConnectIntroModel.Model.FullName + ".json", model);
    }
}

Take the JSON file that gets generated and copy it to the xConnect-web-root/App_Data/Models folder. You’ll also need to copy this JSON file to the search-indexer-root/App_Data/Models folder. In my case, this folder was under xConnect-web-root/App_data/jobs/continuous/IndexWorker/App_data/Models. The services will detect the change and restart automatically.

Using Custom Collection Models in Sitecore

Once you have deployed the JSON files to the various xConnect services, you can start using them immediately with external clients. However, to start using them within a Sitecore context, you have to patch in your custom model to the sitecore/xconnect/runtime node in the configuration, originally defined in /App_Config/Include/Sitecore/XConnect.Client.Configuration/Sitecore.XConnect.Client.config.

Create a new patch file in /App_Config/Custom with the following:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <xconnect>
      <runtime type="Sitecore.XConnect.Client.Configuration.RuntimeModelConfiguration,Sitecore.XConnect.Client.Configuration">
        <schemas hint="list:AddModelConfiguration"> 
              <schema name="xConnectIntroModel" type="Sitecore.XConnect.Client.Configuration.StaticModelConfiguration,Sitecore.XConnect.Client.Configuration">
                  <param desc="modeltype">xConnectIntro.Model.xConnectIntroModel, xConnectIntro.Model</param>
              </schema>
        </schemas>
      </runtime>
    </xconnect>
  </sitecore>
</configuration>

Now that your custom collection model is now patched in to Sitecore, you can start using it there as well!

Source code can be found on GitHub.

Happy Sitecore trails, my friend!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: