HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Manage groups

Describes how to manage groups in the Optimizely Community API.

Optimizely Community API represents a group with the Group class.

An instance of the Group class is constructed with a name (string) and a description (string). An example of this construction is below:

var group = new Group("Marketing Department", "A group for collaborating within the Marketing Department.");

Groups are managed through a service implementing the interface IGroupService. This service lets you persist, retrieve, update, and remove groups you define.

Access an IGroupService

When the Groups feature is installed on an Optimizely 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 groupService = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IGroupService>();

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

Example:

var factory = new EPiServer.Social.Groups.DefaultGroupServiceFactory();
var groupService = factory.Create();

Add a group

To add a group, use the Add(Group) method of the IGroupService. This method accepts an instance of the Group class and returns a reference to an instance of that class, populated with any additional, system-generated data (for example, a unique ID).

IGroupService groupService;

// ...
var group = new Group("Marketing Department", "A group for collaborating within the Marketing Department.");
groupService.Add(group);

The above example invokes the request to add a group synchronously. An example of adding a group asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task < Group > AddGroupAsync(IGroupService groupService) {
  // ...
  var group = new Group("Marketing Department", "A group for collaborating within the Marketing Department.");
  var addGroupTask = groupService.AddAsync(group);

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

  //Wait until the task runs to completion.
  var addedGroup = await addGroupTask;
  return addedGroup;
}

Update a group

To update a group which was previously added through the platform, use the Update(Group) method of the IGroupService.

IGroupService groupService;
Group existingGroup;
// ...
var group = new Group(existingGroup.Id, "New name", "A new description");
groupService.Update(group);

If the Group to be updated does not exist, a GroupDoesNotExistException is thrown.

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

private async Task < Group > UpdateGroupAsync(IGroupService groupService) {
  Group existingGroup;

  // ...
  var group = new Group(existingGroup.Id, "New name", "A new description");
  var updateGroupTask = groupService.UpdateAsync(group);

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

  //Wait until the task runs to completion.
  var updatedGroup = await updateGroupTask;

  return updatedGroup;
}

If the identified Group is a Composite Group, its name and description are updated, and its associated extension data remains intact. For information on Composite Groups, see Extending Groups with Composites.

Retrieve a group

To retrieve a specific instance of a Group, which has previously been added through the platform, use the Get(GroupId) method of IGroupService. This method accepts an instance of the GroupId class, which identifies the Group to retrieve. It returns the instance of the Group class corresponding to that identifier.

IGroupService groupService;

// ...

// Construct a GroupId corresponding to the desired group
var groupId = GroupId.Create("...")
var group = groupService.Get(groupId);

If the requested Group cannot be found, a GroupDoesNotExistException is thrown.

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

private async Task < Group > GetGroupAsync(IGroupService groupService) {
  //...

  // Construct a GroupId corresponding to the desired group
  var groupId = GroupId.Create("...");

  var getGroupTask = groupService.GetAsync(groupId);

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

  //Wait until the task runs to completion.
  var group = await getGroupTask;
  return group;
}

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

The Filter property of the Criteria <GroupFilter> class accepts an instance of the GroupFilter class. This class contains the specifications that let you refine the result set of groups that you want to retrieve.

The properties of the GroupFilter include:

  • Name – Assigning a value (String) to this property refines a result set to Groups with the specified name.
  • GroupIds – Assigning a value (IEnumerable<GroupId>) to this property refines a result set to Groups with IDs included in that collection.

The specifications of the GroupFilter may be applied in conjunction with one another. Each specification assigned a value in the filter further refines the result set (that is, a logical AND).

The example below demonstrates the retrieval of a result page of Groups, which exist in a set of identified groups.

IGroupService groupService;

// ...

// Define a collection identifying the various groups to be retrieved
var knownGroups = new List < GroupId > {
  GroupId.Create("..."),
  GroupId.Create("..."),
  GroupId.Create("...")
};

var criteria = new Criteria < GroupFilter > {
  Filter = new GroupFilter {
    GroupIds = knownGroups
  }
};

var pageOfGroups = groupService.Get(criteria);

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

private async Task < ResultPage < Group >> GetGroupsAsync(IGroupService groupService) {
  // ...

  // Define a collection identifying the various groups to be retrieved
  var knownGroups = new List < GroupId > {
    GroupId.Create("..."),
    GroupId.Create("..."),
    GroupId.Create("...")
  };

  var criteria = new Criteria < GroupFilter > {
    Filter = new GroupFilter {
      GroupIds = knownGroups
    }
  };
  var getGroupTask = groupService.GetAsync(criteria);

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

  //Wait until the task runs to completion.
  var pageOfGroups = await getGroupTask;
  return pageOfGroups;
}

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

  • GroupSortFields.Created
  • GroupSortFields.Id
  • GroupSortFields.Name

The example below demonstrates how to apply sorting rules to order a result set by name, alphabetically from A-Z. A fallback rule, subsequently ordering results with the same name according to when they were created from newest to oldest, is also added.

{
  // ...

  OrderBy = new List < SortInfo > {
    new SortInfo(GroupSortFields.Name, true),
    new SortInfo(GroupSortFields.Created, false)
  }
};

For more details regarding criteria use, including information on paging and sorting, see Criteria in Discover the platform.

Remove a group

To remove a specific instance of a group which has previously been added through the platform, use the Remove(GroupId) method. This method accepts an instance of the GroupId class, which identifies the GroupId to be removed. The result is the deletion of the group corresponding to that ID.

IGroupService groupService;

// ...

// Construct or retrieve an ID for an existing Group.
var groupId = GroupId.Create("...");
groupService.Remove(groupId);
  • If members or content are still associated with the group, the group cannot be deleted.
  • If the group being removed has existing members in the system when the remove operation is attempted, a MemberStillExistsException is thrown.
  • If the group being removed has existing content associations in the system when the remove operation is attempted, an AssociationStillExistsException is thrown.

Remove existing members and content before removing a group.

The above example invokes the request to remove a group synchronously. An example of removing a group asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task RemoveGroupAsync(IGroupService groupService) {
  //...

  // Construct or retrieve an ID for an existing Group.
  var groupId = GroupId.Create("...");

  var removeGroupTask = groupService.RemoveAsync(groupId);

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

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

Extend groups with composites

In its simplest form, a group is just a named aggregation of users and content. You may need to associate additional information with Groups to further describe and shape them. For example, suppose you are leveraging groups within your application to represent an athletic team. In that case, you might capture information describing the team's location, mascot, or the date it originally formed.

Like many of the other Optimizely Community API features, you can extend a Group with data from your design by creating a composite. See Composites in Discover the platform.

Add a composite group

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

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

public class AthleticTeam {
  public string Mascot {
    get;
    set;
  }
  public string Location {
    get;
    set;
  }
  public DateTime Established {
    get;
    set;
  }
}

In the example below, a group is composed of an instance of this extension class:

IGroupService groupService;

// ...

var group = new Group("The Wombats", "A group for The Wombats team.");
var extension = new AthleticTeam {
  Mascot = "Wombat",
    Location = "Nashua",
    Established = new DateTime(5, 1, 2014)
};

var compositeGroup = groupService.Add(group, extension);

The above example invokes the request to add a group synchronously. An example of adding a group asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

private async Task < Composite < Group, AthleticTeam >> AddGroupAsync(IGroupService groupService) {
  // ...

  var group = new Group("The Wombats", "A group for The Wombats team.");
  var extension = new AthleticTeam {
    Mascot = "Wombat",
      Location = "Nashua",
      Established = new DateTime(5, 1, 2014)
  };

  var addGroupTask = groupService.AddAsync(group, extension);

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

  //Wait until the task runs to completion.
  var compositeGroup = await addGroupTask;
  return compositeGroup;
}

Update a composite group

To update a specific instance of a Composite Group, which was previously added through the platform, use the Update(Group,TExtension) method of the IGroupService.

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

public class AthleticTeam {
  public string Mascot {
    get;
    set;
  }
  public string Location {
    get;
    set;
  }
  public DateTime Established {
    get;
    set;
  }
}

In the example below, an existing group is updated with an instance of this extension class:

IGroupService groupService;
var existingGroup;

// ...

var group = new Group(existingGroup.Id, "New team name", "A new description for the group.");
var extension = new AthleticTeam {
  Mascot = "Lion",
    Location = "Nashua",
    Established = new DateTime(6, 1, 2016)
};

groupService.Update(group, extension);

If a Group with the specified ID cannot be found, a GroupDoesNotExistException is thrown.

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

private async Task < Composite < Group, AthleticTeam >> UpdateGroupAsync(IGroupService groupService) {
  var existingGroup;

  // ...

  var group = new Group(existingGroup.Id, "New team name", "A new description for the group.");
  var extension = new AthleticTeam {
    Mascot = "Lion",
      Location = "Nashua",
      Established = new DateTime(6, 1, 2016)
  };

  var updateGroupTask = groupService.UpdateAsync(group, extension);

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

  //Wait until the task runs to completion.
  var updatedGroup = await updateGroupTask;
  return updatedGroup;
}

Retrieve a composite group

To retrieve a specific instance of a Composite Group, which was previously added through the platform, use the Get<TExtension>(GroupId) method. This method accepts an instance of the GroupId class, which identifies the Group to retrieve. It returns the instance of the Composite\<Group,TExtension> class corresponding to that identifier.

IGroupService groupService;

//...

// Construct a GroupId corresponding to the desired group
var groupId = GroupId.Create("...");
var compositeGroup = groupService.Get<MyGroupExtension>(groupId);

If a Composite Group with the specified ID and extension type cannot be found, a GroupDoesNotExistException is thrown.

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

private async Task < Composite < Group, MyGroupExtension >> GetGroupAsync(IGroupService groupService) {
  //...

  // Construct a GroupId corresponding to the desired group
  var groupId = GroupId.Create("...");
  var getGroupTask = groupService.GetAsync < MyGroupExtension > (groupId);

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

  //Wait until the task runs to completion.
  var compositeGroup = await getGroupTask;
  return compositeGroup;
}

To retrieve a collection of Composite Groups, which were previously added through the platform, use the Get<TExtension>(CompositeCriteria\<GroupFilter,TExtension>) method. This method accepts an instance of CompositeCriteria\<GroupFilter,TExtension>, which contains the specifications to retrieve the desired Groups.

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

The ExtensionFilter property of the CompositeCriteria\<GroupFilter,TExtension> class accepts a FilterExpression, which 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 Filter composites in Discover the platform.

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

public class AthleticTeam {
  public string Mascot {
    get;
    set;
  }
  public string Location {
    get;
    set;
  }
  public DateTime Established {
    get;
    set;
  }
}

In the example below, a page of Groups composed with AthleticTeam is retrieved, where the Established property of that extension data contains a date after "1/1/2015".

IGroupService groupService;

// ...

var criteria = new CompositeCriteria < GroupFilter,
  AthleticTeam > {
    ExtensionFilter = FilterExpressionBuilder < AthleticTeam > .Field(e => e.Established).GreaterThan(new DateTime(2015, 1, 1))
  };

var resultPage = groupService.Get(criteria);

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

private async Task < ResultPage < Composite < Group, AthleticTeam >>> GetGroupsAsync(IGroupService groupService) {
  // ...

  var criteria = new CompositeCriteria < GroupFilter,
    AthleticTeam > {
      ExtensionFilter = FilterExpressionBuilder < AthleticTeam > .Field(e => e.Established).GreaterThan(new DateTime(2015, 1, 1))
    };

  var getGroupTask = groupService.GetAsync(criteria);

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

  //Wait until the task runs to completion.
  var pageOfGroups = await getGroupTask;
  return pageOfGroups;
}

The fields of your extension data may also be applied when sorting a result set. The example below demonstrates the use of an extension data field in defining a sorting rule.

var criteria = new CompositeCriteria < GroupFilter,
  AthleticTeam > {
    OrderBy = new List < SortInfo > {
      new SortInfo(new SortField(FilterExpressionBuilder < AthleticTeam > .Field(e => e.Established)), false)
    }
  }