The ININ.IceLib.Configuration namespace contains classes for configuring an IC Server. ININ.IceLib.Configuration has rich support for the RoleConfiguration, UserConfiguration and WorkgroupConfiguration objects, as well as basic support for other objects such as SiteConfiguration and WrapUpCodeConfiguration.

There are a number of classes within the ININ.IceLib.Configuration namespace that provide support to the classes mentioned in the preceding summary. Examples of the supporting classes are enumerations, event argument classes, and delegates used by events within classes.

List-Based Configuration Objects

There are a number of object classes that are used to get properties for configuration objects that can have multiple instances on the server (distinguished by their ConfigurationId). These consist of ListConfigurationObject-derived classes. They are searched, with the results being cached, using a ConfigurationList<(Of <(<'TConfigurationObject, TPropertyEnum>)>)>-derived class. The search is comprised of a QuerySettings<(Of <(<'TConfigurationObject, TPropertyEnum>)>)> instance which encapsulates a filter, a sort, the properties to be retrieved, the rights to be applied, and the result count limit. An example of this type of configuration object list is UserConfigurationList which is used to obtain UserConfiguration instances.

Some of these list-based configuration objects also support being edited, created, or deleted. These consist of EditableListConfigurationObject<(Of <(<'TPropertyEnum>)>)>-derived classes and the EditableConfigurationList<(Of <(<'TConfigurationObject, TPropertyEnum>)>)>-derived classes used to search and cache them. The EditableConfigurationList-derived class has support for create and the EditableListConfigurationObject-derived class has support for edit and delete.

Container-Based Configuration Objects

There are a number of object classes that are used to get properties for configuration objects that can only have a single instance on the server. These consist of ContainerConfigurationObject-derived classes. They are queried, with the results being cached, using a ConfigurationContainer<(Of <(<'TConfigurationObject, TPropertyEnum>)>)>-derived class. The query is comprised of which properties are to be retrieved, and can also be specified with a ContainerQuerySettings<(Of <(<'TConfigurationObject, TPropertyEnum>)>)> instance that encapsulates the properties to be retrieved and the rights to be applied.

Some of these container-based configuration objects also support being edited (but not created or deleted). These consist of EditableContainerConfigurationObject<(Of <(<'TPropertyEnum>)>)>-derived classes. The EditableListConfigurationObject<(Of <(<'TPropertyEnum>)>)>-derived class has support for edit. An example of this type of configuration object list is SystemConfigurationContainer which is used to obtain a SystemConfiguration instance.

List-Based Configuration Objects With a Parent/Child Relationship. There are a number of list-based configuration objects that have a parent-child relationship. A parent-child relationship is one in which the parent object has a property that contains a collection of child objects. Working with these types of objects are a little different from working with a standard list-based object. Currently, the objects that have such a relationship are: Parent object CtiConfiguration, with child object CtiAttributeMapConfiguration; parent object AnalyzerKeywordSetConfiguration, with child object AnalyzerKeywordConfiguration; parent object ScheduleConfiguration, with child object ScheduleRecurrenceConfiguration; and parent object WorkgroupConfiguration, with child object WorkgroupMonitoredMailboxConfiguration.

Querying List-Based Parent/Child Configuration Objects. A number of new steps needs to be completed to be able to query for a parent and child object. These steps involve using a HierarchicalQuerySettings<(Of <(<'TConfigurationObject, TPropertyEnum, TQueryChildrenSettings>)>)> object with an associated QueryChildrenSettings<(Of <(<'TPropertyEnum>)>)>-derived object, in addition to the QuerySettings<(Of <(<'TConfigurationObject, TPropertyEnum>)>)> object.

Adding new List-Based Parent/Child Configuration Objects. Adding a new parent/child configuration object differs only slightly from what is needed to add a typical list-based configuration object. The additional steps include creating the child object, and adding it to the associated collection property on the parent object.

Note

The following are some examples of using the configuration namespace classes. It is assumed that an active session is present, a ConfigurationManager instance has been created with the session, and saved in a variable named "_configurationManager".

Jump to a code example:

Adding a New Workgroup

The following example illustrates how to use configuration to add a new workgroup to the IC Server.

CopyC#
var configurationList = new WorkgroupConfigurationList(_configurationManager);
var configurationObject = configurationList.CreateObject();

// Begin editing the object
configurationObject.PrepareForEdit();

// Set the ID
configurationObject.SetConfigurationId("New Workgroup");

// Set more properties
configurationObject.Extension.Value = "12345";

// Save the object
configurationObject.Commit();

Back to Introduction

Retrieving Id/DisplayName of Viewable Skills

The following example illustrates the bare minimum code needed to retrieve an Id/DisplayName listing of skills. By default, if no specific properties are requested, then only Id/DisplayName will be returned. If no rights are specified, then the results will have the associated view right applied. If no result limit is specified, because only Id and DisplayName will be requested, then an unlimited number of results will be returned.

CopyC#
var configurationList = new SkillConfigurationList(_configurationManager);
var querySettings = configurationList.CreateQuerySettings();

configurationList.StartCaching(querySettings);

foreach (var configurationObject in configurationList.GetConfigurationList())
{
    // Get the ID and DisplayName
    var id = configurationObject.ConfigurationId.Id;
    var displayName = configurationObject.ConfigurationId.DisplayName;

    // Do something else...
}

configurationList.StopCaching();

Back to Introduction

Retrieving All Properties of Administerable Roles

The following example illustrates how to retrieve all the properties of all roles that the session user has administrative rights to. This query will only return a maximum of 300 results because more than 5 properties are being requested.

CopyC#
var configurationList = new RoleConfigurationList(_configurationManager);
var querySettings = configurationList.CreateQuerySettings();

querySettings.SetPropertiesToRetrieveToAll();
querySettings.SetRightsFilterToAdmin();

configurationList.StartCaching(querySettings);

foreach (var configurationObject in configurationList.GetConfigurationList())
{
    // Get the ID and DisplayName
    var id = configurationObject.ConfigurationId.Id;
    var displayName = configurationObject.ConfigurationId.DisplayName;

    // Get some other properties
    foreach (var configurationId in configurationObject.Users.Value)
    {
        // Do something with the user...
        var userId = configurationId.Id;
        var userName = configurationId.DisplayName;
    }

    // Do something else...
}

configurationList.StopCaching();

Back to Introduction

Deleting a Skill

The following example illustrates the code needed to delete a skill from the IC Server. Note that the object where Delete is invoked is an instance of SkillConfiguration.

CopyC#
configurationObject.Delete();

Back to Introduction

Retrieving the Users Assigned to a Specific Role

The following example shows how to query the list of users that are assigned to a specific role. In this example, the only requested property is Users. Additionally, there is a filter placed on the the Id to match the supplied role name.

CopyC#
var configurationList = new RoleConfigurationList(_configurationManager);
var querySettings = configurationList.CreateQuerySettings();

querySettings.SetFilterDefinition(RoleConfiguration.Property.Id, roleName, FilterMatchType.Exact);
querySettings.SetPropertiesToRetrieve(new[] { RoleConfiguration.Property.Users });

configurationList.StartCaching(querySettings);

foreach (var configurationObject in configurationList.GetConfigurationList())
{
    // Do something
}

configurationList.StopCaching();

Back to Introduction

Updating the Current User's Home Phone Number

The following example illustrates the code needed update the home phone number of the current user. The code filters Id with the session's userid, applies the admin rights filter, and only retreives the property being updated. After retrieving the UserConfiguration object, the code updates and commits the phone number value.

CopyC#
var configurationList = new UserConfigurationList(_configurationManager);
var querySettings = configurationList.CreateQuerySettings();

// Get the currently logged on user
querySettings.SetFilterDefinition(UserConfiguration.Property.Id, _session.UserId, FilterMatchType.Exact);
// Since we are updating the object, request admin rights
querySettings.SetRightsFilterToAdmin();
// Request the phone number property
querySettings.SetPropertiesToRetrieve(new[] { UserConfiguration.Property.PersonalInformation_PhoneNumberOfHome1 });

configurationList.StartCaching(querySettings);

var configurationObject = configurationList.GetConfigurationList().FirstOrDefault();

if (configurationObject != null)
{
    // Begin editing the object
    configurationObject.PrepareForEdit();
    // Set the value
    configurationObject.PersonalInformation.PhoneNumberOfHome1.Value = new BasicPhoneNumber(phoneNumber, String.Empty, false);
    // Save the object
    configurationObject.Commit();
}

// Call StopCaching() to clean up resources
configurationList.StopCaching();

Back to Introduction

Handling Validation Exceptions During a Commit

The following example illustrates how to handle ConfigurationValidationExceptions when performing a Commit. For brevity, the needed code to perform a commit is not in this example. See the Updating the Current User's Home Phone Number example to see how to update a configuration object.

CopyC#
try
{
    // The rest of the code needed for Commit() is missing to shorten this example,
    //  see the "UpdateMyPhoneNumber" example to see a full usage of Commit().
    configurationObject.Commit();
}
catch (ConfigurationValidationException ex)
{
    foreach (var configurationValidationIssue in ex.GetValidationIssues<WorkgroupConfiguration.Property>())
    {
        var messsage = configurationValidationIssue.DisplayMessage;
        var property = configurationValidationIssue.PropertyEnum;
        var value = configurationValidationIssue.PropertyValue;
        var validator = configurationValidationIssue.Validator;

        // Do something...
    }
}

Back to Introduction

Watching for Workgroup Changes and Deletions

The following example illustrates how to query a WorkgroupConfigurationList, and monitor it for changes. Because this example is retrieving all properties, only the first 300 matches will be returned.

Note
Change and delete notifications on the watched list will only include those objects that existed at the time the watch was started. For instance, in this code example, once the watch is started, if a new workgroup gets added to the IC Server, it will not be included in this watch. The only way to include a new object after the initial watch, is to stop and restart the current watch.

Note
Notice that the events are subscribed to before the watch is started. In order to guarantee that no notifications are missed, the event handlers need to be subscribed to before the watch is started.

CopyC#
_configurationList = new WorkgroupConfigurationList(_configurationManager);
var querySettings = _configurationList.CreateQuerySettings();

querySettings.SetPropertiesToRetrieveToAll();

// Events will only be fired for objects that match the filtered objects as they existed at the start of the watch.
//  If a new object is added to the IC Server after the watch was started, they will not be included in this watch.
_configurationList.ConfigurationObjectsChanged += ConfigurationObjectsChanged;
_configurationList.ConfigurationObjectsRemoved += ConfigurationObjectsRemoved;
_configurationList.StartWatching(querySettings);

The following example illustrates the changed and removed event handler signatures, and the event arguments parameters.

CopyC#
private static void ConfigurationObjectsChanged(object sender, ConfigurationObjectChangesEventArgs<WorkgroupConfiguration, WorkgroupConfiguration.Property> e)
{
    foreach (var keyValuePair in e.ObjectsChanged)
    {
        // Do something
        var configurationObject = keyValuePair.Key;
        var propertiesChanged = keyValuePair.Value;
    }
}

private static void ConfigurationObjectsRemoved(object sender, ConfigurationWatchEventArgs<WorkgroupConfiguration> e)
{
    foreach (var configurationObject in e.ObjectsAffected)
    {
        // Do something
    }
}

The following example illustrates the code that needs to be run when an IceLib integrated application no longer needs the associated list watch. This could be in cases where, for instance, a form is closed, or when the application receives a ConnectionStateChanged notification where the connection is Down.

CopyC#
if (_configurationList == null || !_configurationList.IsWatching) return;

_configurationList.ConfigurationObjectsChanged -= ConfigurationObjectsChanged;
_configurationList.ConfigurationObjectsRemoved -= ConfigurationObjectsRemoved;
_configurationList.StopWatching();

Back to Introduction

Querying the System Languages

The following example illustrates how to retrieve all of the languages supported on the IC Server. This requires using the SystemConfigurationContainer.

CopyC#
var configurationContainer = new SystemConfigurationContainer(_configurationManager);

configurationContainer.StartCaching(new[]
                                        {
                                            SystemConfiguration.Property.DefaultLanguage,
                                            SystemConfiguration.Property.Languages
                                        });

var configurationObject = configurationContainer.GetConfigurationItem();

// Do something

configurationContainer.StopCaching();

Back to Introduction

Querying Parent and Child Objects (with Analyzer Keywords)

The following example illustrates how to retrieve all of the configured analyzer keywords on the IC Server. Because analyzer keywords represent objects with a parent and a child relationship, querying them requires a few more steps, and involves the following objects: AnalyzerKeywordSetConfigurationList, HierarchicalQuerySettings<(Of <(<'TConfigurationObject, TPropertyEnum, TQueryChildrenSettings>)>)>, QuerySettings<(Of <(<'TConfigurationObject, TPropertyEnum>)>)>, AnalyzerQueryChildrenSettings, AnalyzerKeywordSetConfiguration and AnalyzerKeywordConfiguration.

CopyC#
// Create the parent list object.
var parentConfigurationList = new AnalyzerKeywordSetConfigurationList(_configurationManager);
// Create the parent query settings.
var parentQuerySettings = parentConfigurationList.CreateQuerySettings();
// Create the child query settings.
var childQuerySettings = parentConfigurationList.CreateKeywordQuerySettings();
// Create the query children settings.
var queryChildrenSettings = new AnalyzerQueryChildrenSettings();

// Setup the child query, and assign it to the query children settings property.
childQuerySettings.SetPropertiesToRetrieveToAll();
queryChildrenSettings.Keyword = childQuerySettings;

// Setup the parent query settings, and assign the child query.
// To get the child object, you must be sure to include the child property
// in the query.
parentQuerySettings.SetPropertiesToRetrieveToAll();
parentQuerySettings.SetRightsFilterToView();
// The query children settings must be included to get the child objects.
parentQuerySettings.SetChildQuerySettings(queryChildrenSettings);

// Start caching on the parent query settings.
try
{
    parentConfigurationList.StartCaching(parentQuerySettings);
}
catch
{
    // Do something meaningful here.
}

if (parentConfigurationList.IsCaching)
{
    // Get the configuration list.
    var analyzerKeywordSets = parentConfigurationList.GetConfigurationList();

    foreach (var analyzerKeywordSet in analyzerKeywordSets)
    {
        // Do something with the child objects.
        if (analyzerKeywordSet.Keywords.Value.Count > 0)
        {
        }
    }

    // Cleanup.
    parentConfigurationList.StopCaching();
}

Back to Introduction

Creating Parent and Child Objects (with Analyzer Keywords)

The following example illustrates how to create a new analyzer keyword set with a single analyzer keyword on the IC Server. Because analyzer keywords represent objects with a parent and a child relationship, creating them requires a few more steps, and involves the following objects: AnalyzerKeywordSetConfigurationList, AnalyzerKeywordSetConfiguration and AnalyzerKeywordConfiguration.

CopyC#
// Create the parent list object.
var parentConfigurationList = new AnalyzerKeywordSetConfigurationList(_configurationManager);
// Create the parent object.
var keywordSet = parentConfigurationList.CreateObject();

// Put it in edit mode.
keywordSet.PrepareForEdit();

// Set any needed parent properties.
keywordSet.SetConfigurationId(Guid.NewGuid().ToString());
keywordSet.SetDisplayName("My New Keyword Set");
keywordSet.Category.Value = "Category";

// Setup a single keyword.
// Create the keyword.
var analyzerKeyword = parentConfigurationList.CreateAnalyzerKeyword();

// Put it in edit mode.
analyzerKeyword.PrepareForEdit();

// Set any needed child properties.
analyzerKeyword.SetConfigurationId(Guid.NewGuid().ToString());
analyzerKeyword.SetDisplayName("Keyword");
analyzerKeyword.UserWords.Value.Add("Keyword");

// Add the child object to the parent property.
keywordSet.Keywords.Value.Add(analyzerKeyword);

try
{
    // Save the parent object, which will save the child objects as well.
    keywordSet.Commit();
}
catch (ConfigurationValidationException cvex)
{
    // Handle any validation exceptions
}

Back to Introduction

Setting the DisplayName of a Configuration Object

The following example illustrates how to set the DisplayName for a configuration object. Note that this does not work for the UserConfiguration object - a separate example is available to show how to set that.

CopyC#
var configurationList = new AccessControlGroupConfigurationList(_configurationManager);
var configurationObject = configurationList.CreateObject();

// Begin editing the object
configurationObject.PrepareForEdit();

// Set the ID
configurationObject.SetConfigurationId("ACG ID");

// Set the DisplayName - note that not all objects support setting a DisplayName.
// Documentation on SetDisplayName() shows which objects can have DisplayNames
// that are different from the ConfigurationId.
configurationObject.SetDisplayName("New ACG");

// TODO:  Set more properties

// Save the object
configurationObject.Commit();

Back to Introduction

Setting the DisplayName of a UserConfiguration Object

The following example illustrates how to set the DisplayName for a UserConfiguration object. DisplayNames for these objects are stored in the mailbox properties, and additional work has to be done to set them.

CopyC#
var configurationList = new UserConfigurationList(_configurationManager);
var querySettings = configurationList.CreateQuerySettings();

// Get the currently logged on user
querySettings.SetFilterDefinition(UserConfiguration.Property.Id, _session.UserId, FilterMatchType.Exact);
// Since we are updating the object, request admin rights
querySettings.SetRightsFilterToAdmin();
// Request the mailbox properties - note that we have to retrieve all of the mailbox properties
querySettings.SetPropertiesToRetrieve(
    UserConfiguration.Property.Mailbox_DirectoryMoniker,
    UserConfiguration.Property.Mailbox_DisplayName,
    UserConfiguration.Property.Mailbox_EmailAddress,
    UserConfiguration.Property.Mailbox_MailboxMoniker,
    UserConfiguration.Property.Mailbox_Type);

configurationList.StartCaching(querySettings);

var configurationObject = configurationList.GetConfigurationList().FirstOrDefault();

if (configurationObject != null)
{
    // Create appropriate MailboxSettings, with a new DisplayName.  Other MailboxSettings-derived
    // objects exist, but for simplicity, we'll just use the NoMailboxSettings.
    var mailboxSettings = new NoMailboxSettings("New Display Name");

    // Apply the MailboxSettings - note that this does not save the object to the IC Server.
    configurationObject.Mailbox.ApplyMailboxSettings(mailboxSettings);

    // Save the object
    configurationObject.Commit();
}

configurationList.StopCaching();

Back to Introduction