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

Groups: Content associations

Recommendations [hide]

A group is a named aggregation of users and content. You associate resources with a group by adding them as an association.

In the Episerver Community API, an association is represented with the Association class.

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

For more information on the Episerver Community Async API, see Async API.

Accessing an IAssociationService

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 associationService = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IAssociationService>();

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

Example:

var factory = new EPiServer.Social.Groups.DefaultAssociationServiceFactory();
var associationService = factory.Create();

Adding an association

To add an association, use the Add(Association) method of the IAssociationService. This method accepts an instance of the Association class and returns a reference to a new instance of that class, which was populated with any additional, system-generated, data (for example, a unique ID).

IAssociationService associationService;
GroupId idOfExistingGroup;
Reference resource;

// ...

var association = new Association(resource, idOfExistingGroup);
associationService.Add(association);

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

If the association already exists, a DuplicateAssociationException is thrown.

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

private async Task<Association> AddAssociationAsync(IAssociationService associationService)
  {
    GroupId idOfExistingGroup;
    Reference resource;

    // ...

    var association = new Association(resource, idOfExistingGroup);

    var addAssociationTask = associationService.AddAsync(association);

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

    //Wait until the task runs to completion.
    var addedAssociation = await addAssociationTask;
    return addedAssociation;
  }

Validating an association

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

IAssociationService associationService;
GroupId idOfExistingGroup;
Reference resource;

// ...

bool isAssociation = associationService.IsAssociated(idOfExistingGroup, resource);

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

private async Task<bool> ValidateAssociationAsync(IAssociationService associationService)
  {
    // ...

    GroupId idOfExistingGroup;
    Reference resource;

    // ...

    var isAssociationTask = associationService.IsAssociatedAsync(idOfExistingGroup, resource);

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

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

Removing an association

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

IAssociationService associationService;

//...

// Construct a AssociationId corresponding to the desired association
var associationId = AssociationId.Create("...");
var association = associationService.Get(associationId);

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

private async Task RemoveAssociationAsync(IAssociationService associationService)
  {
    //...
            
    // Construct a AssociationId corresponding to the desired association
    var associationId = AssociationId.Create("...");
    var removeAssociationTask = associationService.RemoveAsync(associationId);

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

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

Retrieving an association

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

IAssociationService associationService;

//...

// Construct a AssociationId corresponding to the desired association
var associationId = AssociationId.Create("...");
var association = associationService.Get(associationId);

If the requested Association cannot be found, an AssociationDoesNotExistException is thrown.

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

private async Task<Association> GetAssociationAsync(IAssociationService associationService)
  {
    //...
            
    // Construct a AssociationId corresponding to the desired association
    var associationId = AssociationId.Create("...");

    var getAssociationTask = associationService.GetAsync(associationId);

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

    //Wait until the task runs to completion.
    var association = await getAssociationTask;
    return association;
  }

You can retrieve a collection of associations, which have previously been added through the platform, by using the Get(Criteria<AssociationFilter>) method. This method accepts an instance of Criteria<AssociationFilter>, which contains the specifications necessary to retrieve the desired Associations.

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

The properties of the AssociationFilter include:

  • Group. Assigning a value (GroupId) to this property refines a result set to Associations of the identified group
  • Resource. Assigning a value (Reference) to this property refines a result set to Associations associated with the identified resource.

The specifications of the AssociationFilter 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 Associations which were assigned to a group.

IAssociationService associationService;
Group existingGroup;

// ...

var criteria = new Criteria<AssociationFilter>
  {
    Filter = new AssociationFilter
      {
            Group = existingGroup.Id
      }
  };
var pageOfAssociations = associationService.Get(criteria);

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

private async Task<ResultPage<Association>> GetAssociationsAsync(IAssociationService associationService)
  {
    Group existingGroup;

    // ...
    var criteria = new Criteria<AssociationFilter>
      {
        Filter = new AssociationFilter
          {
                Group = existingGroup.Id
          }
      };
    var getAssociationTask = associationService.GetAsync(criteria);

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

    //Wait until the task runs to completion.
    var pageOfAssociations = await getAssociationTask;
    return pageOfAssociations;
  }

The AssociationSortFields class exposes a set of fields upon which a result set of associations may be ordered. You can apply these fields to construct sorting rules that you associate with your criteria. These fields include:

  • AssociationSortFields.Group
  • AssociationSortFields.Id
  • AssociationSortFields.Resource

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

var criteria = new Criteria<AssociationFilter>
  {
    // ...

    OrderBy = new List<SortInfo>
      {
        new SortInfo(AssociationSortFields.Group, true)
      }
  }

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

Extending associations with composites

An Association is simply a relationship between a resource and a group. You may need to associate additional information with Associations to further describe and shape them. Continuing an earlier example, where a group represents an athletic team, an association may be leveraged to associate relevant documents (roster, scorecards, and so on) with the team. You might want to capture information describing or categorizing those documents.

Just as you can extend a Group with data of your design, an Association may also be extended by creating a Composite. (For an introduction to Composites, see Composites.)

Adding a composite association

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

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

public class TeamDocument
  {
    public string Category { get; set; }
    public DateTime Modified { get; set; }
  } 

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

IAssociationService associationService;
GroupId existingGroup;
Reference resource;

// ...
var association = new Association(resource, existingGroup);
var extension = new TeamDocument
  {
    Category = "Lineups",
    Modified = new DateTime(2016,4,1)
  };
var compositeAssociation = associationService.Add(association, extension);

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

private async Task<Composite<Association, AthleticTeam>> AddAssociationAsync(IAssociationService associationService)
  {
    // ...
    GroupId existingGroup;
    Reference resource;

    // ...
    var association = new Association(resource, existingGroup);
    var extension = new TeamDocument
      {
        Category = "Lineups",
        Modified = new DateTime(2016,4,1)
      };
    var addAssociationTask = associationService.AddAsync(association, extension);

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

    //Wait until the task runs to completion.
    var compositeAssociation = await addAssociationTask;
    return compositeAssociation;
  }

Updating a composite association

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

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

public class TeamDocument
  {
    public string Category { get; set; }
    public DateTime Modified { get; set; }
  } 

For this example, the IAssociationService must be properly implemented.

IAssociationService associationService;

// ...

// Construct a associationId corresponding to the desired association
AssociationId existingAssociationId;

var newExtension = new TeamDocument
  {
     Category = "Roster Changes",
     Modified = DateTime.Now;
  };
associationService.Update(existingAssociationId, newExtension);

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

private async Task<Composite<Association, TeamDocument>> UpdateAssociationAsync(IAssociationService associationService)
  {
    // ...

    // Construct a associationId corresponding to the desired association
    AssociationId existingAssociationId;

    var newExtension = new TeamDocument
      {
         Category = "Roster Changes",
         Modified = DateTime.Now;
      };
    var updateGroupTask = associationService.UpdateAsync(existingAssociationId, newExtension);

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

    //Wait until the task runs to completion.
    var updatedAssociation = await updateAssociationTask;
    return updatedAssociation;
  }

Retrieving a composite association

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

IAssociationService associationService;

//...

// Construct a AssociationId corresponding to the desired association
var associationId = AssociationId.Create("...");
var compositeAssociation = associationService.Get<MyAssociationExtension>(associationId);

If a Composite Association with the specified ID and extension type cannot be found, an AssociationDoesNotExistException is thrown.

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

private async Task<Composite<Association, MyAssociationExtension>> GetAssociationAsync(IAssociationService associationService)
  {
    //...

    // Construct a AssociationId corresponding to the desired group
    var associationId = AssociationId.Create("...");    
    var getAssociationTask = associationService.GetAsync<MyAssociationExtension>(associationId);

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

    //Wait until the task runs to completion.
    var compositeAssociation = await getAssociationTask;
    return compositeAssociation;
  }

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

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

The ExtensionFilter property of the CompositeCriteria<AssociationFilter,TExtension> class accepts a FilterExpression that lets you specify a Boolean expression to further refine the result set by values represented in 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 TeamDocument
  {
    public string Category { get; set; }
    public DateTime Modified { get; set; }
  }

In the example below, a page of Associations composed with TeamDocument is retrieved, where the document is categorized as a lineup:

IAssociationService associationService;

// ...
var criteria = new CompositeCriteria<AssociationFilter, TeamDocument>
  {
    ExtensionFilter = FilterExpressionBuilder<TeamDocument>.Field(e => e.Category).EqualTo("Lineups")
  };
var pageOfAssociations = associationService.Get(criteria); 

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

private async Task<ResultPage<Composite<Association, TeamDocument>>> GetAssociationsAsync(IAssociationService associationService)
  {
    // ...
    var criteria = new CompositeCriteria<AssociationFilter, TeamDocument>
      {
        ExtensionFilter = FilterExpressionBuilder<TeamDocument>.Field(e => e.Category).EqualTo("Lineups")
      };
    var getAssociationTask = associationService.GetAsync(criteria);

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

    //Wait until the task runs to completion.
    var pageOfAssociations = await getAssociationTask;
    return pageOfAssociations;
  }

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

var criteria = new CompositeCriteria<AssociationFilter, TeamDocument>
  {
    // ...
    OrderBy = new List<SortInfo>
      {
        new SortInfo(new SortField(FilterExpressionBuilder<TeamDocument>.Field(e => e.Modified)), false)
      }
  };

For more details about 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]