Manage comments
Explains how to use ICommentService to manage comments in the Optimizely Community API platform.
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:
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:
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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Updated 6 months ago