---
title: Manage comments
slug: cms-12/api/managing-comments
docTags: 
createdAt: 2026-08-07T16:45:42.000Z
---

In the Optimizely Community API, comments are managed through a service implementing the interface `ICommentService`. This service provides the ability to persist and retrieve comments that you define.

## Access an ICommentService

If the `Comments` feature is installed on an Optimizely Content Management System (CMS) site with the feature's site integration package; you can get an instance of this service from the inversion of control (IoC) container.

Example:

```csharp
var commentService = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<ICommentService>();
```

If the feature is installed on a non-Optimizely CMS site, you can get an instance of this service from the default factory class provided in the package.

Example:

```csharp
var factory = new EPiServer.Social.Comments.DefaultCommentServiceFactory();
var commentService = factory.Create();
```

### Add a comment

You can add a comment by using the `Add(Comment)` method of the `ICommentService`. This method accepts an instance of the `Comment` class and returns a reference to an instance of that class, populated with any additional, system-generated data (for example, a unique ID).

```csharp
ICommentService commentService;

// ...

var parentContent = Reference.Create("resource://identifier/for/a/resource");
var body = "This is wonderful content!";
var isVisible = true;

var comment = new Comment(parentContent, body, isVisible);

commentService.Add(comment);
```

The above 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.

```csharp
private async Task<Comment> AddCommentAsync(ICommentService commentService) {
  var parentContent = Reference.Create("resource://identifier/for/a/resource");
  var author = Reference.Create("user://identifier/for/a/user");
  var body = "This is wonderful content!";
  var isVisible = true;

  var comment = new Comment(parentContent, author, body, isVisible);

  var addCommentTask = commentService.AddAsync(comment);

  //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 comment

You can update a comment that was previously added through the platform by using the `Update(Comment)` method of the `ICommentService`. This method accepts a comment, which must be populated with a `CommentId` that identifies the existing comment.

```csharp
ICommentService commentService;
Comment existingComment;

// ...

var parentContent = Reference.Create("resource://identifier/for/a/resource");
var author = Reference.Create("user://identifier/for/a/user");
var body = "This is wonderful content!";
var isVisible = true;

var comment = new Comment(existingComment.Id, parentContent, author, body, isVisible);

commentService.Update(comment);
```

If the comment to be updated does not exist, a `CommentDoesNotExistException` is thrown.

The above 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.

```csharp
private async Task<Comment> UpdateCommentAsync(ICommentService commentService) {
  Comment existingComment;

  // ...

  var parentContent = Reference.Create("resource://identifier/for/a/resource");
  var author = Reference.Create("user://identifier/for/a/user");
  var body = "This is wonderful content!";
  var isVisible = true;

  var comment = new Comment(existingComment.Id, parentContent, author, body, isVisible);

  var updateCommentTask = commentService.UpdateAsync(comment);

  //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 comment

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

```csharp
ICommentService commentService;
// ...

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

If the requested comment cannot be found, a `CommentDoesNotExistException` is thrown.

The above 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.

```csharp
private async Task<Comment> GetCommentAsync(ICommentService commentService) {
  Comment existingComment;
  // ...

  // Construct a CommentId corresponding to the desired comment
  var commentId = CommentId.Create("...");

  var getCommentTask = commentService.GetAsync(commentId);

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

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

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

The Filter property of the `Criteria<CommentFilter>` 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 properties of the `CommentFilter` include:

- `Author` – Assigning a value (Reference) to this property refines a result set to comments whose author matches the given value.
- `Parent` – Assigning a value (Reference) to this property refines a result set to comments that are immediate children of the resource or comments identified by that value.
- `Ancestor` – Assigning a value (Reference) to this property refines a result set to comments that are descendants of the resource or comments identified by that value. The identified ancestor may appear anywhere in the lineage of a result (as a parent, grandparent, great-grandparent, and so on).
- `Visibility` – Assigning a value (Visibility) to this property refines a result set to comments according to whether or not it is intended to be presented within the application.

The specifications of the `CommentFilter` may be applied in conjunction with one another. Each specification, which is assigned a value in the filter, further refines the result set (for example, a logical AND). The example below demonstrates the retrieval of a result page of comments, which are immediate children of a particular resource.

```csharp
ICommentService commentService;
// ...

var parentContent = Reference.Create("resource://identifier/for/a/resource");
var criteria = new Criteria<CommentFilter> {
  Filter = new CommentFilter {
    Parent = parentContent
  }
};
var pageOfComments = commentService.Get(criteria);
```

In the next example, a similar approach is taken to demonstrate the retrieval of a result page of comments, which are descendants of a particular comment.

```csharp
ICommentService commentService;
CommentId idOfExistingComment;
// ...

var ancestralComment = idOfExistingComment.ToReference();
var criteria = new Criteria<CommentFilter> {
  Filter = new CommentFilter {
    Ancestor = ancestralComment
  }
};
var pageOfContents = commentService.Get(criteria);
```

In the above 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.

```csharp
private async Task<ResultPage<Comment>> GetCommentsAsync(ICommentService commentService) {
  // ...

  var parentContent = Reference.Create("resource://identifier/for/a/resource");
  var criteria = new Criteria<CommentFilter> {
    Filter = new CommentFilter {
      Parent = parentContent
    }
  };
  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;
}
```

### Sort comments

The `CommentSortFields` class exposes a set of fields upon which a result set of comments may be ordered. These fields may be applied when constructing sorting rules you associate with your criteria. These fields include:

- `CommentSortFields.Id`
- `CommentSortFields.Created`
- `CommentSortFields.Author`

The example below demonstrates the application of sorting rules to order a result set by comment creation date, from oldest to newest.

```csharp
var criteria = new Criteria<CommentFilter> {
  OrderBy = new List<SortInfo> {
    new SortInfo(CommentSortFields.Created, true)
  }
};
```

### Remove a comment

You can remove a comment by using the `Remove(CommentId)` method of the `ICommentService`. This method accepts an instance of the `CommentId` class. It is important to consider that when a comment is deleted, the descendants of that comment are also deleted. When a comment is deleted, the parent comment of the deleted comment is updated with the corrected `HasChildren` and `HasVisibleChildren` properties. When a comment is deleted, the corresponding extension data is removed from the system.

```csharp
ICommentService commentService;
// ...

var commentId = CommentId.Create("resource://identifier/for/a/resource");
commentService.Remove(commentId);
```

The above example invokes the request to remove a comment synchronously. The following example removes a comment asynchronously using the asynchronous overload with C#'s async and awaits keywords.

```csharp
private async Task RemoveCommentAsync(ICommentService commentService) {
  // ...

  var commentId = CommentId.Create("resource://identifier/for/a/resource");
  commentService.Remove(commentId);
  var removeCommentTask = commentService.RemoveAsync(criteria);

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

  //Wait until the task runs to completion.
  await removeCommentTask;
}
```

For details regarding criteria use, including information on paging and sorting, see *Criteria* in [Discover the platform](docId\:NKmGS-fLtRQIYLEWZfb69).

## Best practices to manage comments

Comments, by nature, are a unique form of content. Generally, there is a high frequency of publication and a high frequency of reads. With this in mind, applications should avoid unnecessarily escalating the frequency and volume of those operations.

### Page result sets

Paging is an essential strategy in managing your application's performance. It lets you limit the volume of a result set by requesting comments in batches. Studies have found that viewers often don't read beyond the first few comments. So, limit result pages to 5-10 results and prompt users to reveal more. Limiting pages to a size that is proportionate to your audience's reading habits minimizes the performance impact of transferring results. For information on paging result sets, see *PageInfo* in [Discover the platform](docId\:NKmGS-fLtRQIYLEWZfb69).

### Display replies on demand

You can further reduce the volume of result sets by prompting users to reveal replies when they are interested in digging deeper into a thread. The Optimizely Community API lets you retrieve comments that are immediate children of a parent comment. If users choose to view a comment's replies, use this mechanism to reveal the next level of the comment tree.

### Render comments optimistically

A common approach to optimizing applications is to perform actions optimistically, assuming a positive outcome for an action without waiting for it to complete.

As you implement user experiences for publishing comments, consider presenting a comment optimistically. If a user composes a comment, the application asynchronously publishes it through the platform, and the user interface is updated immediately. In doing so, your application provides instant user feedback while avoiding a roundtrip to the platform to retrieve a largely redundant page of comments.

### Cache comments

Comments are often contributed to an application with significant frequency. However, they are not particularly volatile because they are not often updated or edited. Employing a caching strategy for comments within your application can be advantageous in reducing the volume of requests for retrieval to the platform.
