Loading...
Area: Episerver Community API
Applies to versions: 1 and higher

Managing groups

Recommendations [hide]

In the Episerver Community API, a group is represented 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 provides the ability to persist, retrieve, update, and remove groups that you define.

Accessing an IGroupService

When the Groups feature is installed to an Episerver 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 to a non-Episerver 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();

Adding 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 a new instance of that class, which has been 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);

In the above example, the request to add a group is invoked 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;
  }

Updating 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.

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

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 more information on Composite Groups, see Extending Groups with Composites.)

Retrieving 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.

In the above example, the request to retrieve a group is invoked 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 have previously been 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 which is 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 in the construction of sorting rules that 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 the use of criteria, including information on paging and sorting, see Criteria.

Removing 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.

In the above example, the request to remove a group is invoked 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;
  }

Extending groups with composites

A group, in its simplest form, 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, if you are leveraging groups within your application to represent an athletic team, you might capture information describing the team's location, mascot, or the date when it originally formed.

Like many of the other Episerver Community API features, you can extend a Group with data of your design by creating a Composite. (For an introduction to Composites, see Composites.)

Adding 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 a new 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 with 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);

In the above example, the request to add a group is invoked 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;
  }

Updating 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 a new 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.

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

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;
  }

Retrieving 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.

In the above example, the request to retrieve a group is invoked 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 further refine the result set by values represented within your extension data. (For more information on this type of filter, see Composite Criteria and Filtering Composites.)

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 the definition of a sorting rule.

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

For more details on using criteria, including information on paging and sorting, see Criteria.

Do you find this information helpful? Please log in to provide feedback.

Last updated: Nov 01, 2016

Recommendations [hide]