Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Extend comments with composites

Describes how to associate additional information with a comment to support your application's use cases.

You may need to associate additional information with a comment to support your application's use cases. A common example is the implementation of a product review.

A review is fundamentally a comment centered around the reviewer's commentary and is often accompanied by additional information. It may refer to a rating (or series of ratings) or include purchase details. The Optimizely Community API lets you extend a comment with your design data to achieve such solutions by creating a Composite. See also Composites in Discover the platform.

Add a composite comment

To save a composite comment, which you have defined, use the Add<TExtension>(Comment,TExtension) method of the ICommentService. This method accepts an instance of the Comment class and an instance of TExtension. It returns an instance of Composite<Comment,TExtension>.

Consider the following class, which represents a sample of extension data:

public class ReviewExtension {
  public DateTime PurchaseDate {
    get;
    set;
  }
  public string QualityRating {
    get;
    set;
  }
}

In the following example, a comment is composed with an instance of this extension class:

ICommentService commentService;
DateTime dateOfPurchase;
RatingId ratingOfQuality;

// ...

var parentProduct = Reference.Create("resource://identifier/for/a/resource");
var author = Reference.Create("user://identifier/for/a/user");
var body = "This product is great!";
var isVisible = true;

var comment = new Comment(parentProduct, author, body, isVisible);
var extension = new ReviewExtension
  {
    PurchaseDate = dateOfPurchase,
    QualityRating = ratingOfQuality.Id
  };

var compositeComment = commentService.Add(comment, extension);

The previous example invokes the request to add a comment synchronously. Below is an example of adding a comment asynchronously using the asynchronous overload with C#'s async and await keywords.

private async Task<Composite<Comment, ReviewExtension>> AddCommentAsync(ICommentService commentService) {
  DateTime dateOfPurchase;
  RatingId ratingOfQuality;

  // ...

  var parentProduct = Reference.Create("resource://identifier/for/a/resource");
  var author = Reference.Create("user://identifier/for/a/user");
  var body = "This product is great!";
  var isVisible = true;

  var comment = new Comment(parentProduct, author, body, isVisible);
  var extension = new ReviewExtension {
    PurchaseDate = dateOfPurchase,
      QualityRating = ratingOfQuality.Id
  };

  var addCommentTask = commentService.AddAsync(comment, extension);

  //Do other application specific work in parallel while the task executes.
  //....

  //Wait until the task runs to completion.
  var newComment = await addCommentTask;
  return newComment;
}

Update a composite comment

To update a specific instance of a composite comment, which was added through the platform, use the Update<TExtension>(Comment,TExtension) method of the ICommentService. Consider the following class, which represents a sample of extension data:

public class ReviewExtension
  {
    // ...
  }

In the following example, an existing comment is updated with an instance of this extension class:

ICommentService commentService;

// ...

// Construct or retrieve an ID for an existing comment.
var idOfExistingComment = CommentId.Create("...");
var parentProduct = Reference.Create("resource://identifier/for/a/resource");
var author = Reference.Create("user://identifier/for/a/user");
var body = "This product is great!";
var isVisible = true;

var comment = new Comment(idOfExistingComment, parentProduct, author, body, isVisible);
var extension = new ReviewExtension
  {
    // ...
  };

commentService.Update(comment, extension);

If a comment with the specified ID cannot be found, a CommentDoesNotExistException is thrown.

The previous example invokes the request to update a comment synchronously. Below is an example of updating a comment asynchronously using the asynchronous overload with C#'s async and await keywords.

private async Task<Composite<Comment, ReviewExtension>> UpdateCommentAsync(ICommentService commentService) {
  // ...

  // Construct or retrieve an ID for an existing comment.
  var idOfExistingComment = CommentId.Create("...");
  var parentProduct = Reference.Create("resource://identifier/for/a/resource");
  var author = Reference.Create("user://identifier/for/a/user");
  var body = "This product is great!";
  var isVisible = true;

  var comment = new Comment(idOfExistingComment, parentProduct, author, body, isVisible);
  var extension = new ReviewExtension {
    // ...
  };

  var updateCommentTask = commentService.UpdateAsync(comment, extension);

  //Do other application specific work in parallel while the task executes.
  //....

  //Wait until the task runs to completion.
  var updatedComment = await updatedCommentTask;
  return updatedComment;
}

Retrieve a composite comment

To retrieve a specific instance of a Composite Comment, which was previously added through the platform, use the Get<TExtension>(CommentId) method. This method accepts an instance of the CommentId class, which identifies the comment to be retrieved. It returns instances of the Composite<Comment,TExtension> class corresponding to that identifier.

ICommentService commentService;

//...

// Construct a CommentId corresponding to the desired comment
var commentId = CommentId.Create("...");
var compositeComment = commentService.Get<ReviewExtension>(commentId);

If a composite comment with the specified ID and extension type cannot be found, a CommentDoesNotExistException is thrown.

The previous example invokes the request to retrieve a comment synchronously. An example of retrieving a comment asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task<Composite<Comment, ReviewExtension>> GetCommentAsync(ICommentService commentService) {
  //...

  // Construct a CommentId corresponding to the desired comment
  var commentId = CommentId.Create("...");
  var getCommentTask = commentService.GetAsync<ReviewExtension>(commentId);

  //Do other application specific work in parallel while the task executes.
  //....

  //Wait until the task runs to completion.
  var compositeComment = await getCommentTask;
  return compositeComment;
}

To retrieve a collection of composite comments, which were previously added through the platform, use the Get<TExtension>(CompositeCriteria<CommentFilter,TExtension>) method. This method accepts an instance of CompositeCriteria<CommentFilter,TExtension>, which contains the specifications necessary to retrieve the desired comments.

The Filter property of the CompositeCriteria<CommentFilter,TExtension> class accepts an instance of the CommentFilter class. This class contains specifications that let you refine the result set of comments you want to retrieve.

The ExtensionFilter property of the CompositeCriteria<CommentFilter,TExtension> class accepts a FilterExpression that lets you specify a Boolean expression to refine the result set further by values represented within your extension data. (For information on this type of filter, see Composite Criteria and Filtering composites in Discover the platform.

Consider the following class, which represents a sample of extension data:

public class ReviewExtension {
  public DateTime PurchaseDate {
    get;
    set;
  }
}

In the following example, a page of comments composed with ReviewExtension is retrieved, where the value of PurchaseDate represents a date after January 1, 2016:

ICommentService commentService;

// ...

var criteria = new CompositeCriteria<CommentFilter, ReviewExtension> {
    ExtensionFilter = FilterExpressionBuilder<ReviewExtension> .Field(e => e.PurchaseDate).GreaterThan(new DateTime(2016, 1, 1).ToUniversalTime())
  };

var resultPage = commentService.Get(criteria);

In the previous example, the request to retrieve comments is invoked synchronously. An example of retrieving comments asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task<ResultPage<Composite<Comment, ReviewExtension>>> GetCommentsAsync(ICommentService commentService) {
  // ...

  var criteria = new CompositeCriteria<CommentFilter, ReviewExtension> {
      ExtensionFilter = FilterExpressionBuilder<ReviewExtension> .Field(e => e.PurchaseDate).GreaterThan(new DateTime(2016, 1, 1).ToUniversalTime())
    };

  var getCommentsTask = commentService.GetAsync(criteria);

  //Do other application specific work in parallel while the task executes.
  //....

  //Wait until the task runs to completion.
  var pageOfComments = await getCommentTask;
  return pageOfComments;
}

Extension data fields may also be applied to sort your result set. The following example demonstrates using an extension data field to define a sorting rule.

var criteria = new CompositeCriteria<CommentFilter, ReviewExtension> {
    // ...

    OrderBy = new List<SortInfo> {
      new SortInfo(new SortField(FilterExpressionBuilder<ReviewExtension> .Field(t => t.PurchaseDate)), true),
    }
  };