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

Roles provide a means of labeling or categorizing members within your digital community. They are defined within your application as you see fit. They may be assigned to members of a group or span multiple groups.

Roles do not bestow any particular permission, status, or responsibility. This leaves your application free to apply meaning to roles as appropriate.

In the Optimizely Community API, a role is represented with the `Role` class.

Roles are managed through a service implementing the interface `IRoleService`. This service provides the ability to persist, retrieve, assign, and remove `Roles` that you define.

## Access an IRoleService

When the `Groups` 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 roleService = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IRoleService>();
```

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 within the package.

Example:

```csharp
var factory = new EPiServer.Social.Groups.DefaultRoleServiceFactory();
var roleService = factory.Create();
```

## Add a role

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

```csharp
IRoleService roleService;

// ...

var role = new Role("Moderator");
roleService.Add(role);
```

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

```csharp
private async Task<Role> AddRoleAsync(IRoleService roleService) {
  // ...

  var role = new Role("Moderator");

  var addRoleTask = roleService.AddAsync(role);

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

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

## Remove a role

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

```csharp
IRoleService roleService;

// ...

// Construct or retrieve an ID for an existing role.
var roleId = RoleId.Create("...");
roleService.Remove(roleId);
```

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

```csharp
private async Task RemoveRoleAsync(IRoleService roleService) {
  //...

  // Construct or retrieve an ID for an existing role.
  var roleId = RoleId.Create("...");

  var removeRoleTask = roleService.RemoveAsync(roleId);

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

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

## Retrieve a role

To retrieve a specific instance of a `Role`, which was previously added through the platform, use the `Get(RoleId)` method of `IRoleService`. This method accepts an instance of the `RoleId` class, which identifies the `Role` to retrieve. It returns the instance of the `Role` class corresponding to that identifier.

```csharp
IRoleService roleService;

//...

// Construct a RoleId corresponding to the desired role
var roleId = RoleId.Create("...");
var role = roleService.Get(roleId);
```

If the requested `Role` cannot be found, a `RoleDoesNotExistException` is thrown.

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

```csharp
private async Task<Role> GetRoleAsync(IRoleService roleService) {
  //...

  // Construct a RoleId corresponding to the desired role
  var roleId = RoleId.Create("...");

  var getRoleTask = roleService.GetAsync(roleId);

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

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

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

The `Filter` property of the `Criteria<RoleFilter>` class accepts an instance of the `RoleFilter` class. This class contains the specifications, which let you refine the result set of roles you want to retrieve.

The properties of the `RoleFilter` include:

- `Name`  – Assigning a value (`String`) to this property refines a result set to Roles with the specified name.
- `RoleIds` – Assigning a value (`IEnumerable<RoleId>`) to this property refines a result set to Roles identified in that collection.

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

The example below demonstrates the retrieval of a result page of Roles with the name "Moderator":

```csharp
IRoleService roleService;

// ...

var criteria = new Criteria<RoleFilter> {
  Filter = new RoleFilter {
    Name = "Moderator"
  }
};

var pageOfRoles = roleService.Get(criteria);
```

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

```csharp
private async Task<ResultPage<Role>> GetRolesAsync(IRoleService roleService) {
  // ...

  var criteria = new Criteria<RoleFilter> {
    Filter = new RoleFilter {
      Name = "Moderator"
    }
  };

  var getRolesTask = roleService.GetAsync(criteria);

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

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

The `RoleSortFields` class exposes a set of fields upon which a result set of roles may be ordered. You can apply these fields to construct sorting rules associated with your criteria. These fields include:

- `RoleSortFields.Id`
- `RoleSortFields.Name`

The example below demonstrates how to apply sorting rules to order your result set by name, alphabetically from A-Z.

```csharp
var criteria = new Criteria<RoleFilter> {
  // ...

  OrderBy = new List<SortInfo> {
    new SortInfo(RoleSortFields.Name, true)
  }
};
```

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

## Assign a role

You can assign a role, which was previously added through the platform, to an existing member by using the `Assign(RoleAssignment)` method of the `IRoleService`. This method accepts an instance of the `RoleAssignment` class, which identifies the target member and the role to be assigned.

```csharp
IRoleService roleService;
RoleId existingRole;
MemberId existingMember;

// ...

var assignment = new RoleAssignment(existingMember, existingRole);
roleService.Assign(assignment);
```

If the identified `Role` cannot be found, a `RoleDoesNotExistException` is thrown.

If the identified `Member` cannot be found, a `MemberDoesNotExistException` is thrown.

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

```csharp
private async Task AssignRoleAsync(IRoleService roleService) {
  RoleId existingRole;
  MemberId existingMember;

  // ...

  var assignment = new RoleAssignment(existingMember, existingRole);
  roleService.Assign(assignment);

  // ...

  var assignmentTask = roleService.AssignAsync(assignment);

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

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

## Unassign a role

To unassign a role from a member, which was previously assigned through the platform, use the `Unassign(RoleAssignment)` method of the `IRoleService`. This method accepts an instance of the `RoleAssignment` class, which describes the role assignment to be removed.

```csharp
IRoleService roleService;
RoleId existingRole;
MemberId existingMember;

// ...

var assignment = new RoleAssignment(existingMember, existingRole);
roleService.Unassign(assignment);
```

If the identified `Role` cannot be found, a `RoleDoesNotExistException` is thrown.

If the identified `Member` cannot be found, a `MemberDoesNotExistException` is thrown.

In the above example, the request to unassign a role from a member is invoked synchronously. An example of unassigning a role from a member asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

```csharp
private async Task UnassignRoleAsync(IRoleService roleService) {
  RoleId existingRole;
  MemberId existingMember;

  // ...

  var assignment = new RoleAssignment(existingMember, existingRole);
  roleService.Unassign(assignment);

  // ...

  var unassignmentTask = roleService.UnAssignAsync(assignment);

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

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

## Validate a role assignment

To validate that a role was assigned to a member, use the `IsAssigned(RoleAssignment)` of the `IRoleService`. This method accepts an instance of the `RoleAssignment` class, describing the assignment to be validated. The method returns a Boolean indicating whether or not the identified role was assigned to the identified member.

```csharp
IRoleService roleService;
RoleId existingRole;
MemberId existingMember;

// ...

var assignmentToVerify = new RoleAssignment(existingMember, existingRole);
bool hasRole = roleService.IsAssigned(assignmentToVerify);
```

In the above example, the request to validate if a member is assigned a role is invoked synchronously. An example of validating a role for a member asynchronously using the asynchronous overload with C#'s async and await keywords is described below.

```csharp
private async Task<bool> IsAssignedAsync(IRoleService roleService) {
  // ...
  RoleId existingRole;
  MemberId existingMember;

  // ...
  var assignmentToVerify = new RoleAssignment(existingMember, existingRole);
  var assignmentVerifyTask = roleService.IsAssignedAsync(assignmentToVerify);

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

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

## Extend roles with composites

A role is a label that may be applied to members within your application. You may need to associate additional information with roles to describe and shape them further. Consider the following examples:

- A role in your application is intended to confer permission or privilege. You might want to associate information describing access rules with it.
- Your application gamifies status within a group. You might want to associate scoring information with a role.

Just as you can extend a `Group` with data of your design, a `Role` may also be extended by creating a `Composite`. For an introduction to Composites, see *Composites* in [Discover the platform](docId\:NKmGS-fLtRQIYLEWZfb69).

### Add a composite role

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

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

```csharp
public class TeamStatus {
  public int Points {
    get;
    set;
  }
}
```

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

```csharp
IRoleService roleService;

// ...
var role = new Role("All-Star");
var extension = new TeamStatus {
  Points = 100
};

roleService.Add(role, extension);
```

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

```csharp
private async Task<Composite<Role, TeamStatus>> AddRoleAsync(IRoleService roleService) {
  // ...
  var role = new Role("All-Star");
  var extension = new TeamStatus {
    Points = 100
  };
  var addRoleTask = roleService.AddAsync(role, extension);

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

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

### Update a composite role

To update a specific instance of a Composite Role, which was previously added through the platform, use the `Update<TExtension>(RoleId, TExtension)` method of the `IRoleService`. This method accepts an instance of the `RoleId` class and an instance of `TExtension`. It returns an instance of `Composite\<Role,TExtension>`.

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

```csharp
public class TeamStatus {
  public int Points {
    get;
    set;
  }
}
```

In the example below, assume that the `roleService` and `existingRoleId` are properly instantiated.

```csharp
IRoleService roleService;

// Construct a RoleId corresponding to the desired role
RoleId existingRoleId;

// ...

var newExtension = new TeamStatus {
  Points = 200
};

roleService.Update(existingRoleId, extension);
```

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

```csharp
private async Task<Composite<Role, TeamStatus>> UpdateRoleAsync(IRoleService roleService) {
  // Construct a RoleId corresponding to the desired role
  RoleId existingRoleId;

  // ...

  var newExtension = new TeamStatus {
    Points = 200
  };

  var updateRoleTask = roleService.UpdateAsync(existingRoleId, newExtension);

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

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

### Retrieve a composite role

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

```csharp
IRoleService roleService;

//...

// Construct a RoleId corresponding to the desired role
var roleId = RoleId.Create("...");
var compositeRole = roleService.Get<MyRoleExtension>(roleId);
```

If a Composite Role with the specified ID and extension type cannot be found, a `RoleDoesNotExistException` is thrown.

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

```csharp
private async Task<Composite<Role, MyRoleExtension>> GetRoleAsync(IRoleService roleService) {
  //...

  // Construct a RoleId corresponding to the desired role
  var roleId = RoleId.Create("...");

  var getRoleTask = roleService.GetAsync<MyRoleExtension>(roleId);

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

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

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

The `Filter` property of the `CompositeCriteria[RoleFilter,TExtension]` class accepts an instance of the `RoleFilter` class. This class contains the specifications which let you refine the result set of `Roles` you want to retrieve.

The `ExtensionFilter` property of the `CompositeCriteria\<RoleFilter,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.

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

```csharp
public class TeamStatus {
  public int Points {
    get;
    set;
  }
}
```

In the example below, a page of `Roles` composed with `TeamStatus` is retrieved, where the status is worth more than 50 points:

```csharp
IRoleService roleService;

// ...

var criteria = new CompositeCriteria<RoleFilter, TeamStatus> {
    ExtensionFilter = FilterExpressionBuilder<TeamStatus> .Field(e => e.Points).GreaterThan(50)
  };

var pageOfRoles = roleService.Get(criteria);
```

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

```csharp
private async Task<ResultPage<Composite<Role, TeamStatus>>> GetRolesAsync(IRoleService roleService) {
  // ...

  var criteria = new CompositeCriteria<RoleFilter, TeamStatus> {
      ExtensionFilter = FilterExpressionBuilder<TeamStatus> .Field(e => e.Points).GreaterThan(50)
    };

  var getRolesTask = roleService.GetAsync(criteria);

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

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

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.

```csharp
var criteria = new CompositeCriteria<RoleFilter, TeamStatus> {
    // ...
    OrderBy = new List<SortInfo> {
      new SortInfo(new SortField(FilterExpressionBuilder<TeamStatus> .Field(e => e.Points)), true)
    }
  };
```
