AWS Developer Blog

Enhancements to the DynamoDB SDK

by Pavel Safronov | on | in .NET | Permalink | Comments |  Share

The release of AWS SDK for .NET version 2.1.0 has introduced a number of changes to the high-level Amazon DynamoDB classes. Now, less markup is required to use classes with DynamoDBContext, as the SDK now infers reasonable default behavior. You can customize this behavior through app.config/web.config files and during run time through the SDK. In this blog post, we discuss the impact of this change and the new ways you can customize the behavior of DynamoDBContext.

Attributes

With previous versions of the .NET SDK, classes that were used with DynamoDBContext had to have attributes on them specifying the target table, the hash/range keys, and other data. The classes looked like this:

[DynamoDBTable("Movies")]
public class Movie
{
    [DynamoDBHashKey]
    public string Title { get; set; }

    [DynamoDBRangeKey(AttributeName = "Released")]
    public DateTime ReleaseDate { get; set; }

    public List<string> Genres { get; set; }

    [DynamoDBProperty(Converter = typeof(RatingConverter))]
    public Rating Rating { get; set; }

    [DynamoDBIgnore]
    public string Comment { get; set; }

    [DynamoDBVersion]
    public int Version { get; set; }
}

As of version 2.1.0 of the SDK, some of the information that the attributes provided is now being inferred from the target table and the class. You can also provide this information in the app.config/web.config files. In the following section, we show how it’s possible to remove all markup from our Movie class, either by removing the now-optional attributes or by moving the configuration to app.config files.

First, however, let’s look at the various types of attributes that are available and what it means to remove them.

Table attribute

Removing the DynamoDBTable attribute now forces DynamoDBContext to use the class name as the target table name. So for the class SampleApp.Models.Movie, the target table would be "Movie".

Key attributes

Some attributes, such as DynamoDBHashKey, DynamoDBRangeKey, and various SecondaryIndex attributes, are now inferred from the DynamoDB table. So unless you were using those attributes to specify an alternate property name or a converter, it is now safe to omit those attributes from your class definition.

Client-side attributes

There are also attributes that are "client-side", in that there is no information stored about them in DynamoDB, so DynamoDBContext can make no inferences about them. These are DynamoDBIgnore, DynamoDBVersion, DynamoDBProperty, as well as any other attributes that were used to specify an attribute name or a converter. Removing these attributes alters the behavior of your application, unless you’ve added corresponding attribution information to your app.config/web.config file.

App.config

The new release of the SDK adds a way to configure how DynamoDBContext operates data through app.config/web.config files.

To better illustrate this new functionality, here is a modified class definition for the class Movie where all DynamoDB attributes have been removed, and a corresponding app.config which provides functionality identical to what we first started with.

public class Movie
{
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public List<string> Genres { get; set; }
    public Rating Rating { get; set; }
    public string Comment { get; set; }
    public int Version { get; set; }
}
<configuration>
  <configSections>
    <section name="aws" type="Amazon.AWSSection, AWSSDK"/>
  </configSections>
  
  <aws>
    <dynamoDB>
      <dynamoDBContext>
        <mappings>
          <map type="SampleApp.Models.Movie, SampleDLL" targetTable="Movies">
            <property name="ReleaseDate" attribute="Released" />
            <property name="Rating" converter="SampleApp.Models.RatingConverter, SampleDLL" />
            <property name="Comment" ignore="true" />
            <property name="Version" version="true" />
          </map>
        </mappings>
      </dynamoDBContext>
    </dynamoDB>
  </aws>

</configuration>

Table aliases and prefixes

With this release, we have also added the ability to specify table aliases. You can now reconfigure the target table for a class without updating its DynamoDBTable attribute, or even for a class that is missing this attribute. This new feature is in addition to the already-existing prefix support, which allows simple separation of tables based on a common prefix.

Below is a simple .NET class named "Studio" that has no attributes. The configuration for this class is stored in the "Studios" table. Additionally, we have configured a prefix through the config, so the actual table where the class Studio is stored will be "Test-Studios".

// No DynamoDBTable attribute, so DynamoDBContext assumes the
// target table is "Studio"
public class Studio
{
    public string StudioName { get; set; }
    public string Address { get; set; }
    // other properties
}
<configuration>
  <configSections>
    <section name="aws" type="Amazon.AWSSection, AWSSDK"/>
  </configSections>
  
  <aws>
    <dynamoDB>
      <dynamoDBContext tableNamePrefix="Test-">
        <tableAliases>
          <alias fromTable="Studio" toTable="Studios" />
        </tableAliases>
      </dynamoDBContext>
    </dynamoDB>
  </aws>

</configuration>

You can use aliases for both attributed and non-attributed classes. Note that the SDK first applies the configured aliases, then applies the prefix.

For more information on the updated configuration section, see the .NET developer guide.

AWSConfigs

All of the preceding configuration settings are also accessible through code, so you can modify the mappings, aliases, and prefixes during application run time. This is done using the Amazon.AWSConfigs.DynamoDBConfig.Context property. In the following code sample, we show how to modify the current prefix, configure a new alias, update an existing alias, and update a converter for the Movie.Rating property.

var contextConfig = Amazon.AWSConfigs.DynamoDBConfig.Context;

// set the prefix to "Prod-"
contextConfig.TableNamePrefix = "Prod-";

// add and update aliases
contextConfig.AddAlias(new TableAlias("Actor", "Actors"));
contextConfig.TableAliases["Studio"] = "NewStudiosTable";

// replace converter on "Rating" property
var typeMapping = contextConfig.TypeMappings[typeof(Movie)];
var propertyConfig = typeMapping.PropertyConfigs["Rating"];
propertyConfig.Converter = typeof(RatingConverter2);

Note: changes to these settings will take effect only for new instances of DynamoDBContext.

For more information on setting these configurations, see the .NET developer guide.