HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Membership

Describes how to use members in the Optimizely Community (formerly Social) API.

A group is a named aggregation of users and content. Users are associated with a group by adding them as members.

Members are represented by the Member class.

Members are managed through a service implementing the interface IMemberService. This service provides the ability to persist, retrieve, and remove Members that you define.

Access an IMemberService

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:

var memberService = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IMemberService>();

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.

var factory = new EPiServer.Social.Groups.DefaultMemberServiceFactory();
var memberService = factory.Create();

Add a member

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

IMemberService memberService;
GroupId idOfExistingGroup;
Reference user;

// ...
var member = new Member(user, idOfExistingGroup);
memberService.Add(member);

If the identified group cannot be found, a GroupDoesNotExistException is thrown.

If the member already exists, a DuplicateMemberException is thrown.

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

private async Task<Member> AddMemberAsync(IMemberService memberService) {
  GroupId idOfExistingGroup;
  Reference user;

  // ...
  var member = new Member(user, idOfExistingGroup);
  var addMemberTask = memberService.AddAsync(member);

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

  //Wait until the task runs to completion.
  var addedMember = await addMemberTask;
  return addedMember;
}

Validate a member

To validate that a user is a member of a group, use the IsMember(GroupId,Reference) method of the IMemberService. This method accepts an instance of the GroupId class, identifying the target group, and an instance of the Reference class, identifying the target user. The method returns a Boolean, indicating whether or not the identified user is a member of the identified group.

IMemberService memberService;
GroupId idOfExistingGroup;
Reference user;

// ...
bool isMember = memberService.IsMember(idOfExistingGroup, user);

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

private async Task<bool> ValidateMemberAsync(IMemberService memberService) {
  GroupId idOfExistingGroup;
  Reference user;

  // ...
  var isMemberTask = memberService.IsMemberAsync(idOfExistingGroup, user);

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

  //Wait until the task runs to completion.
  var isValid = await isMemberTask;
  return isValid;
}

Remove a member

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

IMemberService memberService;

// ...

// Construct or retrieve an ID for an existing member.
var memberId = MemberId.Create("...");
memberService.Remove(memberId);

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

private async Task RemoveMemberAsync(IMemberService memberService) {
  //...

  // Construct or retrieve an ID for an existing member.
  var memberId = MemberId.Create("...");
  var removeMemberTask = memberService.RemoveAsync(memberId);

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

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

Retrieve a member

You can retrieve a specific instance of a Member, which was previously added through the platform by using the Get(MemberId) method of IMemberService. This method accepts an instance of the MemberId class, which identifies the Member to retrieve. It returns the instance of the Member class corresponding to that identifier.

IMemberService memberService;

//...

// Construct a MemberId corresponding to the desired member
var memberId = MemberId.Create("...");
var member = memberService.Get(memberId);

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

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

private async Task<Member> GetMemberAsync(IMemberService memberService) {
  //...

  // Construct a MemberId corresponding to the desired member
  var memberId = MemberId.Create("...");
  var getMemberTask = memberService.GetAsync(memberId);

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

  //Wait until the task runs to completion.
  var member = await getMemberTask;
  return member;
}

To retrieve a collection of members that were previously added through the platform, use the Get(Criteria) method. This method accepts an instance of Criteria, which contains the specifications to retrieve desired Members.

The Filter property of the Criteria class accepts an instance of the MemberFilter class. This class contains the specifications that let you refine the result set of Members you want to retrieve. The properties of the MemberFilter class include:

  • Group – Assigning a value (GroupId) to this property refines a result set to Members of the identified group.
  • MemberIds – Assigning a value (IEnumerable) to this property refines a result set to Members identified in the collection.
  • Role – Assigning a value (RoleId) to this property refines a result set to Members assigned the identified role.
  • User – Assigning a value (Reference) to this property refines a result set to Members associated with the identified user.

The specifications of the MemberFilter 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 Members assigned to a group.

IMemberService memberService;
Group existingGroup;

// ...

var criteria = new Criteria<MemberFilter> {
  Filter = new MemberFilter {
    Group = existingGroup.Id
  }
};
var pageOfMembers = memberService.Get(criteria);

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

private async Task<ResultPage<Member>> GetMembersAsync(IMemberService memberService) {
  Group existingGroup;

  // ...
  var criteria = new Criteria<MemberFilter> {
    Filter = new MemberFilter {
      Group = existingGroup.Id
    }
  };
  var getMembersTask = memberService.GetAsync(criteria);

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

  //Wait until the task runs to completion.
  var pageOfMembers = await getMembersTask;
  return pageOfMembers;
}

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

  • MemberSortFields.Group
  • MemberSortFields.Id
  • MemberSortFields.User

The example below demonstrates how to apply sorting rules to order your result set by group ID in ascending order.

var criteria = new Criteria<MemberFilter> {
  // ...
  OrderBy = new List<SortInfo> {
    new SortInfo(MemberSortFields.Group, true)
  }
};

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

Extend members with composites

A Member is a relationship between a user and a group. You may need to associate additional information with members to describe and shape them further. Continuing an earlier example, where a group represents an athletic team, a member may represent a player on the team. You might want to capture information identifying the player's uniform number or primary position.

Just as you can extend a Group with data of your design, a Member may also be extended by creating a Composite. For an introduction to Composites, see Composites in Discover the platform.

This section explains the synchronous and asynchronous APIs of the member service that support extending members with composites.

Add a composite member

To save a Composite Member that you defined, use the Add<TExtension>(Member, TExtension) method of the IMemberService. This method accepts an instance of the Member class and an instance of TExtension. It returns an instance of Composite<Member,TExtension>.

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

public class Player {
  public int UniformNumber {
    get;
    set;
  }
  public string Position {
    get;
    set;
  }
}

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

IMemberService memberService;
GroupId existingGroup;
Reference user;

// ...
var member = new Member(user, existingGroup);
var extension = new Player {
  UniformNumber = 2,
    Position = "Shortstop"
};
var compositeMember = memberService.Add(member, extension);

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

private async Task<Composite<Member, Player>> AddMemberAsync(IMemberService memberService) {
  // ...
  GroupId existingGroup;
  Reference user;

  // ...
  var member = new Member(user, existingGroup);
  var extension = new Player {
    UniformNumber = 2,
      Position = "Shortstop"
  };
  var addMemberTask = memberService.AddAsync(member, extension);

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

  //Wait until the task runs to completion.
  var compositeMember = await addMemberTask;
  return compositeMember;
}

Update a composite member

To update a specific instance of a Composite Member, which was previously added through the platform, use the Update<TExtension>(MemberId, TExtension) method of the IMemberService. This method accepts an instance of the MemberId class and an instance of TExtension. It returns an instance of Composite<Member,TExtension>.

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

public class Player {
  public int UniformNumber {
    get;
    set;
  }
  public string Position {
    get;
    set;
  }
}

For this example, the below IMemberService is properly implemented

IMemberService memberService;

// ...

// Construct a MemberId corresponding to the desired member
MemberId existingMemberId;
var newExtension = new Player {
  UniformNumber = 3,
    Position = "Pitcher"
};
memberService.Update(existingMemberId, newExtension);

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

private async Task<Composite<Member, Player>> UpdateMemberAsync(IMemberService memberService) {
  // ...

  // Construct a MemberId corresponding to the desired member
  MemberId existingMemberId;
  var newExtension = new Player {
    UniformNumber = 3,
      Position = "Pitcher"
  };
  var updateMemberTask = memberService.UpdateAsync(existingMemberId, newExtension);

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

  //Wait until the task runs to completion.
  var updatedMember = await updateMemberTask;
  return updatedMember;
}

Retrieve a composite member

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

IMemberService memberService;

//...

// Construct a MemberId corresponding to the desired member
var memberId = MemberId.Create("...");
var compositeMember = memberService.Get<MyMemberExtension>(memberId);

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

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

private async Task<Composite<Member, MyMemberExtension>> GetMemberAsync(IMemberService memberService) {
  //...

  // Construct a MemberId corresponding to the desired member
  var memberId = MemberId.Create("...");
  var getMemberTask = memberService.GetAsync<MyMemberExtension>(memberId);

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

  //Wait until the task runs to completion.
  var compositeMember = await getMemberTask;
  return compositeMember;
}

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

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

The ExtensionFilter property of the CompositeCriteria<MemberFilter,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. (For information on this type of filter, see Composite Criteria and Filtering Composites in Discover the platform.

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

public class Player {
  public int UniformNumber {
    get;
    set;
  }
  public string Position {
    get;
    set;
  }
}

In the example below, a page of Members composed with Player is retrieved, where the players have a position of "Shortstop":

IMemberService memberService;

// ...

var criteria = new CompositeCriteria<MemberFilter,
  Player> {
    ExtensionFilter = FilterExpressionBuilder<Player> .Field(e => e.Position).EqualTo("Shortstop")
  };
var pageOfMembers = memberService.Get(criteria);

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

private async Task<ResultPage<Composite<Member, Player>>> GetMembersAsync(IMemberService memberService) {
  // ...
  var criteria = new CompositeCriteria<MemberFilter,
    Player> {
      ExtensionFilter = FilterExpressionBuilder<Player> .Field(e => e.Position).EqualTo("Shortstop")
    };
  var getMembersTask = memberService.GetAsync(criteria);

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

  //Wait until the task runs to completion.
  var pageOfMembers = await getMembersTask;
  return pageOfMembers;
}

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

var criteria = new CompositeCriteria<MemberFilter,
  Player> {
    // ...

    OrderBy = new List<SortInfo> {
      new SortInfo(new SortField(FilterExpressionBuilder<Player> .Field(e => e.UniformNumber)), true)
    }
  };

For details about using criteria, including information on paging and sorting, see Criteria in Discover the platform.