Having fun coding a DirectSmile Cross Media Data Relations

The Crossmedia version 5 comes with many new features and today I picked one that totally thrills me. Actually, I think that it’s way too cool to name it Data Relations, what is rather obfuscating the real power of this new feature. To show you why I figure Crossmedia Data Relations really rock, I want to share with you an example I made. I will spread the example over two posts, and this post here is the first one that demonstrates the implementation of a Data Relation. The second post will cover how to access a Data Relation from inside a Crossmedia campaign. But first, let me explain what a Data Relation is.

Crossmedia Data Relations

A Data Relation is a relation between the campaign database, you add to your cross media template, and other table(s) from a different data source. Such a data source can be almost everything you have in mind, for example a third party database or a web service. The data relation is the logic that glues tables from those two data sources together.

A Data Relation is a .Net assembly that comes with a pluggable interface based on the Managed Extensibility Framework (MEF). It has the charming advantage that such an assembly already has everything it needs to be accessible by DSMX. All you need to add is code to communicate with your data source to return data tables back to DSMX (which is pretty easy, as you will see).

What you need to create your own Data Relation

Because a Data Relation is a .Net Framework assembly you need Microsoft Visual Studio to build your sources. A Visual Studio Express is fair enough. It doesn’t matter if your are friend with C# or prefer Visual Basic.NET, you should have basic experiences in one of those .NET languages though. My sample is written in VB.NET by the way.

Data Relations example

Sharpen your tools is important in almost every field and especially in software development. That’s why I have one side project for over ten years now that I continuously rewrite every now and then. The application is a web based DVD management software that keeps track of your movies, if they are in the shelf or borrowed by a friend. Adding new movies is done by typing the title of the movie into a web form. A request is then sent to amazon to get all movie details. Those details are then persisted in a database.

To show you how a DSMX data relation could be implemented I extracted the part that queries Amazon web services. The data relation in other words can do a search for a title against Amazon and return a table that contains detailed information about movies you searched for. If you search for Batman, for instance, Amazon will return certainly a long list of movies.

Implementation. Setting up the project

I will not go to much into detail, because Christoph wrote a very good documentation which you will find pretty straight forward, I promise. It describes thoroughly all methods and properties the interface provides and an top it includes sample code.

Enough talk, let’s start with an empty Class Library project in Visual Studio and call it SearchAmazon. We need the following references to be added to out project:

  • System.ComponentModel.Composition (what is in fact the Extensibility Framework)
  • DataRelationInterfaces.dll ( a component that provides us with the necessary interfaces by DirectSmile)

After that we can remove the class or module that came with the Visual Studio project template a add new class and name it SearchAmazon as well.

Because our class should be exposed to DSMX later on, we must decelerate the class with the Export and the ExportMetaData attribute.

We also want to implement two interfaces called IDataRelation and IDataRelation_LoadTableNameWithParameters.

All that done the body of your class should look like this:

clip_image002

Implementation. Adding logic to your class

First we need a display name for our relation that is shown later in the Data Relations dialog of the DSMX designer.

Public ReadOnly Property DisplayName As String Implements DataRelationInterfaces.IDataRelation.DisplayName
        Get
            Return "Amzon Movie Search"
        End Get
End Property

Then we have to decide what parameters we like to pass from our campaign to the Data Relation:

  • the movie title we search for
  • the Amazon Web Services Developer Id
  • the secret developer for Amazon Web Services
Public Sub GetMetaData(AccountID As Integer, Language As String, MetaData As DataRelationInterfaces.Objects.IhtDataProviderMetaData) Implements DataRelationInterfaces.IDataRelation.GetMetaData
        MetaData.AddParameter("AWSSKeyId", "Amazon Web Services Developer ID", "", True)
        MetaData.AddParameter("AWSSecretKey", "Amazon Web Services Secret Key", "", True)
        MetaData.AddParameter("title", "Movie title", "", False)
End Sub

Later, in the Data Relations dialog, those parameters are exposed by name and description and we can add values to them. The last parameter of the AddParameter method is of interest, if that boolean is set to true a password text field is shown and typed-in characters are hidden.

Next we implement the GetTableNames method. Although this method allows a list of tables, as the method name implies, we just add a single table to the collection, holding our search result.

Public Sub GetTableNames(AccountID As Integer, Language As String, IhtDataProviderTablesList As DataRelationInterfaces.Objects.IhtDataProviderTablesList) Implements DataRelationInterfaces.IDataRelation_LoadTableNamesWithParameters.GetTableNames
        IhtDataProviderTablesList.AddTable("Amazon search result")
End Sub

There a lot more properties we can implement what makes the navigation in our Data Relation much more convenient, like support for column selection, column filtering, order by or paging. But this would extend this little example, but please refer to the documentation if you are interested. I, for the moment, return just false in all those properties, which means it’s not supported.

Public ReadOnly Property supportsColumnSelection As Boolean Implements DataRelationInterfaces.IDataRelation.supportsColumnSelection
        Get
            Return False
        End Get
End Property

Public ReadOnly Property SupportsDistinct As Boolean Implements DataRelationInterfaces.IDataRelation.SupportsDistinct
        Get
            Return False
        End Get
End Property

Public ReadOnly Property SupportsFilter As Boolean Implements DataRelationInterfaces.IDataRelation.SupportsFilter
        Get
            Return False
        End Get
End Property

Public ReadOnly Property SupportsOrderBy As Boolean Implements DataRelationInterfaces.IDataRelation.SupportsOrderBy
        Get
            Return False
        End Get
End Property

Public ReadOnly Property SupportsPaging As Boolean Implements DataRelationInterfaces.IDataRelation.SupportsPaging
        Get
            Return False
        End Get
End Property

Now to the most important method, the LoadData method. As the name implies, the method loads the data into our Data Relation table. The implementation does three things:

  • It validates the parameters passed from the campaign manager
  • It sends a search request to the Amazon web services
  • It adds the appropriate fields to our Data Relations table and fills the table with the search result
Public Sub LoadData(Table As DataRelationInterfaces.Objects.IhtDataTable) Implements DataRelationInterfaces.IDataRelation.LoadData
        Dim title As String = Table.GetParameterValue("title")
        Dim secretdeveloperKey As String = Table.GetParameterValue("AWSSecretKey")
        Dim developerId As String = Table.GetParameterValue("AWSSKeyId")

        if String.IsNullOrEmpty(title)
            Throw New ArgumentException("Movie title parameter must have a value.") 
        End If

        if String.IsNullOrEmpty(developerId)
            Throw New ArgumentException("AWS Developer Id parameter must have a value") 
        End If

        if String.IsNullOrEmpty(secretdeveloperKey)
            Throw New ArgumentException("AWS Secret Key parameter must have a value.") 
        End If

        Dim result As List(Of Movie)
        Dim itmLookUp As New Amazon.ItemLookup(developerId,secretdeveloperKey)

        result = itmLookUp.SearchByTitle(title)

        If result IsNot Nothing Then

            AddFields(Table)

               For Each m In result
                    Addrow(m, Table)
               Next

         End If

 End Sub

 Private Sub AddFields(ByRef table As IhtDataTable)
        table.AddField("ID")
        table.AddField("Name")
        table.AddField("Actor1Name")
        table.AddField("Actor3Name")
        table.AddField("Actor2Name")
        table.AddField("DirectorName")
        table.AddField("EAN")
        table.AddField("ASIN")
        table.AddField("PublishDate")
        table.AddField("Publisher")
        'Todo: Add more fields here ...
End Sub

 Private Sub Addrow(m As Movie, byref table As IhtDataTable)

        Dim r As IhtDataTableRow
        r = table.AddRow
        r.AddValue(table.RowCount + 1) 
        r.AddValue(m.Name)
        r.AddValue(m.Actor1Name)
        r.AddValue(m.Actor3Name)
        r.AddValue(m.Actor2Name)
        r.AddValue(m.DirectorName)
        r.AddValue(m.EAN)
        r.AddValue(m.ASIN)
        r.AddValue(m.PublishDate)
        r.AddValue(m.Publisher)
        'Todo: Add more values here ...
    End Sub

The actual call to Amazon is abstracted into a helper class called ItemLookup. That calls takes our AWS logon credentials in the constructor and provides one simple method called SearchByTitle. That method returns a list of Movie, which is a simple type that contains a set of properties. The names of the properties will become the field names of our table, which are added in the AddFields method. While iterating through the search result the AddRow method takes the Movie type and adds it the row collection of the Data Relation table.Throwing an exception inside a Data Relation is bubbled through the interface and directly visible in the DSMX Designer. The LoadData method takes advantage of this while validating the parameters. Very handy by the way.

Conclusion

With Data Relations we have a powerful tool in hand that offers us new opportunities to merge data from different data sources into our campaign data.

As we will see in the next post, this feature can really play it’s strength in building rich client applications using the Crossmedia Designer. In my opinion, as a software developer, this flexibility must not be underestimated. Software development is in a process of moving from the ivory tower where just a few people were able to aggregate data and build reporting applications, to a point where the architectural plumbing is more and more available or generated automatically and a majority of people can start building applications using those automatically aggregated data. The Crossmedia Designer is an excellent example!

About Oliver Dehne
Father of two little boys, good boys. Sometimes I like coding, trying to be a good developer.

One Response to Having fun coding a DirectSmile Cross Media Data Relations

  1. Pingback: Creating a DirectSmile Cross Media mobile application that consumes a Data Relation « Welcome to Olivers Blog

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 )

Google photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s

%d bloggers like this: