Please ensure Javascript is enabled for purposes of website accessibility
Powered by Zoomin Software. For more details please contactZoomin

AVEVA™ Work Tasks

Custom Role Provider Fetching Roles from SQL and Users from Active Directory

Custom Role Provider Fetching Roles from SQL and Users from Active Directory

  • Last UpdatedJun 10, 2024
  • 11 minute read

Setup: Open a new .NET Class Library project, provide the namespace and class name for the project accordingly and add reference to "Workflow.NET.NET2.dll" from [AVEVA Work Tasks Installed Path]\AVEVA\Work Tasks\Bin folder.

PROCEDURE

DLL REFERENCE

Workflow.NET.NET2

System.DirectoryServices

NAMESPACE USED

System

System.IO

System.Collections.Generic

System.Text

System.Collections

System.Collections.Specialized

System.Data

System.Xml

System.DirectoryServices

System.Security.Cryptography

System.Text.RegularExpressions

Sample Code

To support various type of Active Directory, you need to use appropriate APIs. Example, for RODC use ReadonlyServer authenticationType while creating instance of DirectoryEntry.

using Skelta.Core;

using Skelta.Entity;

using Skelta.Entity.RoleEntityProvider;

using System;

using System.Collections;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.DirectoryServices;

using System.IO;

using System.Xml;

using Workflow.NET;

using Workflow.NET.Interfaces;

using Workflow.NET.Storage;

namespace CustomUserEntityProvider

{

public class Roles : DataSourceProviderBase, IRoleEntityDataSourceProvider, ISkeltaAddInProvider

{

bool _IsConnectionValid = false;

string _ConnectionString;

string _SQLConnectionString;

string _LDAPConnectionString;

string _ApplicationName;

private string _UserID, _Password, sDataSourceType;

private bool _IsPasswordEncrypted = false;

private Workflow.NET.Log log = new Workflow.NET.Log();

private string _LDAPServer, _LDAPSearchBase, _LDAPBaseFilter;

private SearchScope _SearchScope;

string _ProviderPrefix = "";

private Config config = new Config();

private ReferralChasingOption _ReferralChasing;

private int _SizeLimit;

private TimeSpan _TimeOut;

private Log logger = new Log();

#region IRoleEntityDataSourceProvider Members

/// <summary>

/// Name of the Repository

/// </summary>

public string ApplicationName

{

get

{

return this._ApplicationName;

}

set

{

this._ApplicationName = value;

}

}

/// <summary>

/// Connection string

/// </summary>

public string ConnectionString

{

get

{

return this._ConnectionString;

}

set

{

this._ConnectionString = value;

}

}

/// <summary>

/// SQL Connection string

/// </summary>

public string SQLConnectionString

{

get

{

return this._SQLConnectionString;

}

set

{

this._SQLConnectionString = value;

}

}

/// <summary>

/// LDAP Connection string

/// </summary>

public string LDAPConnectionString

{

get

{

return this._LDAPConnectionString;

}

set

{

this._LDAPConnectionString = value;

}

}

/// <summary>

/// The identifier type value should always be string.

/// It's always string as the type for user entity provider will always be /// string.

/// </summary>

public string EntityIdentifierType

{

get

{

return "string";

}

}

/// <summary>

/// Getting the information like SizeLimit,Timeout,Referral Chasing from the /// definition xml

/// </summary>

internal class XmlPropertyHandler

{

private XmlDocument xmlDoc;

/// <summary>

/// Loads the definition xml value to the xml document

/// </summary>

/// <param name="xmlString">Definition xml is passed as string</param>

public XmlPropertyHandler(string xmlString)

{

xmlDoc = new XmlDocument();

xmlDoc.Load(new StringReader(xmlString));

}

/// <summary>

/// Getting the value of Searchscope[Subtree,base etc] from the xml document

/// </summary>

/// <returns></returns>

internal SearchScope GetSearchScope()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("SearchScope");

if (xnl == null || xnl.Count == 0)

return SearchScope.Subtree; //Default Search Scope;

string SearchScopeString = xnl.Item(0).InnerText.ToUpperInvariant().Trim();

if (SearchScopeString == "BASE")

{

return SearchScope.Base;

}

else

{

if (SearchScopeString == "ONELEVEL")

return SearchScope.OneLevel;

else

return SearchScope.Subtree;

}

}

/// <summary>

/// Checks whether password is encrypted or not

/// </summary>

/// <returns></returns>

internal bool IsPasswordEncrypted()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("AuthenticationPassword");

if (xnl == null || xnl.Count == 0)

return false; //Default Settings;

if (xnl.Item(0).Attributes["IsEncrypted"] == null)

{

return false;

}

string IsPasswordEncryptedString = xnl.Item(0).Attributes["IsEncrypted"].Value.ToUpperInvariant().Trim();

if (IsPasswordEncryptedString == "TRUE")

{

return true;

}

else

{

return false;

}

}

//Getting the sizelimit from the xml document

internal int GetSizeLimit()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("SizeLimit");

if (xnl == null || xnl.Count == 0)

return 0;

string PageSizeString = xnl.Item(0).InnerText.ToUpperInvariant().Trim();

int PageSize = 0;

try

{

PageSize = int.Parse(PageSizeString);

}

catch { }

return PageSize;

}

//Getting the referral chasing value from the xml document

internal ReferralChasingOption GetReferralChasing()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("ReferralChasing");

if (xnl == null || xnl.Count == 0)

return ReferralChasingOption.External; //Default Referral Chasing Value;

string RCString = xnl.Item(0).InnerText.ToUpperInvariant().Trim();

if (RCString == "NONE")

{

return ReferralChasingOption.None;

}

else

{

if (RCString == "ALL")

return ReferralChasingOption.All;

else

{

if (RCString == "SUBORDINATE")

return ReferralChasingOption.Subordinate;

else

return ReferralChasingOption.External;

}

}

}

//Getting Timeout value from the xml document

internal TimeSpan GetTimeOut()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("TimeOut");

if (xnl == null || xnl.Count == 0)

return TimeSpan.FromSeconds(-1.0);

string TimeOutString = xnl.Item(0).InnerText.ToUpperInvariant().Trim();

double Seconds;

try

{

Seconds = double.Parse(TimeOutString);

}

catch

{

Seconds = -1.0;

}

return TimeSpan.FromSeconds(Seconds);

}

//Getting LDAPServer value from the xml document

internal string GetLDAPServer()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("LDAPServer");

if (xnl == null || xnl.Count == 0)

return "LDAP://";

string s = xnl.Item(0).InnerText.Trim();

if (!s.EndsWith("/"))

{

s += "/";

}

return s;

}

//Getting LDAPSearchBase value from the xml document

internal string GetLDAPSearchBase()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("LDAPSearchBase");

if (xnl == null || xnl.Count == 0)

return "";

return xnl.Item(0).InnerText.Trim();

}

//Getting Domain name from the xml document

internal string GetDomainName()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("DomainName");

if (xnl == null || xnl.Count == 0)

return "";

return xnl.Item(0).InnerText.Trim();

}

//Getting Base filter value from the xml document

internal string GetBaseFilter()

{

XmlNodeList xnl = xmlDoc.GetElementsByTagName("LDAPBaseFilter");

if (xnl == null || xnl.Count == 0)

return "";

return xnl.Item(0).InnerText.Trim();

}

}

/// <summary>

/// Getting all the roles from sql table

/// </summary>

/// <returns> string i.e. all the roles from the table</returns>

public string[] GetAllRoles()

{

// When search is performed on role lookup , the context informaiton of search can be got using ther object

Skelta.Repository.Web.Lookup.RoleExecutionContextInfo searchContextInfo = Skelta.Repository.Web.Lookup.RoleExecutionContext.GetRoleExecutionContext();

string[] StrRolesArray = { };

StringCollection StrRoleCollection = new StringCollection();

System.Data.IDataReader idrRoles;

try

{

if (_IsConnectionValid)

{

// Modify the query as per your table details

string StrSQl = "";

if (searchContextInfo == null)

StrSQl = "SELECT DISTINCT Role FROM users WHERE Role is not NULL ORDER BY Role";

else

StrSQl = "SELECT DISTINCT Role FROM users WHERE Role is not NULL AND Role like '%" + searchContextInfo.RoleSearchString + "%' ORDER BY Role";

using (IDataHandler dbHandler = DataHandlerFactory.GetDataHandler(this.SQLConnectionString, "sql server"))

{

idrRoles = dbHandler.ExecuteReader(StrSQl);

while (idrRoles.Read())

{

int il1 = StrRoleCollection.Add(idrRoles.GetString(0));

}

idrRoles.Close();

StrRolesArray = new string[StrRoleCollection.Count];

StrRoleCollection.CopyTo(StrRolesArray, 0);

}

}

}

catch (Exception ex)

{

logger.LogError(ex, "@@Error while getting the SkeltaRoleProvider GetAllRoles");

}

return StrRolesArray;

}

//Getting DirectoryEntry object

private DirectoryEntry GetDirectoryEntry(string Path)

{

// To access an RODC environment appropriate flag need to be set or use alternate active directory API's. As an example

AuthenticationTypes authenticationTypesForSearch = AuthenticationTypes.Secure | AuthenticationTypes.ReadonlyServer | AuthenticationTypes.ServerBind;

DirectoryEntry de = new DirectoryEntry(Path,null,null, authenticationTypesForSearch);

return de;

}

/// <summary>

/// Collection of unique users id's which belongs to the Role.

/// The Keys for the colleciton hold the unique identifier of the user & the value could be name or any custom value.

/// </summary>

/// <param name="resource"></param>

/// <returns></returns>

public Dictionary<object, string> GetUsersInRole(string roleName)

{

Dictionary<object, string> StrUsersInRoleArray = new Dictionary<object, string>();

try

{

using (DirectoryEntry entry = GetDirectoryEntry(_LDAPConnectionString))

{

using (DirectorySearcher deSearch = new DirectorySearcher())

{

deSearch.SearchRoot = entry;

deSearch.Filter = "(&(objectClass=group) (cn=" + roleName + "))";

SearchResultCollection results = deSearch.FindAll();

if (results.Count > 0)

{

try

{

using (DirectoryEntry group = GetDirectoryEntry(results[0].Path))

{

object members = group.Invoke("Members", null);

foreach (object member in (IEnumerable)members)

{

try

{

using (DirectoryEntry x = new DirectoryEntry(member))

{

string user = x.Properties["sAMAccountName"].Value.ToString();

StrUsersInRoleArray.Add(user, user);

}

}

catch (Exception e)

{

throw e;

}

}

}

}

catch (Exception e)

{

throw e;

}

}

}

}

}

catch (Exception ex)

{

throw new Workflow.NET.ActiveDirectoryException(Skelta.Core.DS.SeverityLevel.Information, "Error while retrieving users from role (" + roleName + ")" + ex.Message, new Skelta.Core.ApplicationObject(RepositoryName));

}

return StrUsersInRoleArray;

}

/// <summary>

/// Get the roles associated to a user.

/// Called from Queue or security for getting the users associated to a role after role selection

/// </summary>

/// <param name="resource"></param>

/// <returns></returns>

public string[] GetRolesForUser(Workflow.NET.Resource resource)

{

StringCollection StrRoleForUserCollection = new StringCollection();

string[] StrRolesForUserArray = { };

try

{

using (DirectoryEntry entry = GetDirectoryEntry(_LDAPConnectionString))

{

using (DirectorySearcher mySearcher = new DirectorySearcher(entry))

{

mySearcher.Filter = "(&(objectClass=user) (cn=" + ((resource.Properties.Name.Value != null && resource.Properties.Name.Value.ToString() != "") ? resource.Properties.Name.Value.ToString().ToLowerInvariant() : resource.Properties.Identifier.Value.ToString().ToLowerInvariant()) + "))";

mySearcher.PropertiesToLoad.Add("memberOf");

int propertyCount;

SearchResult myresult = mySearcher.FindOne();

propertyCount = myresult.Properties["memberOf"].Count;

string dn;

int equalsIndex = 0;

for (int i = 0; i <= propertyCount - 1; i++)

{

dn = (string)myresult.Properties["memberOf"][i];

string strRoles = dn.Trim("CN=".ToCharArray()).Split(',')[0];

if (equalsIndex == -1)

{

return null;

}

StrRoleForUserCollection.Add(strRoles);

}

}

}

StrRolesForUserArray = new string[StrRoleForUserCollection.Count];

StrRoleForUserCollection.CopyTo(StrRolesForUserArray, 0);

}

catch (Exception ex)

{

if (ex.GetType() == typeof(System.NullReferenceException))

{

throw new Workflow.NET.ActiveDirectoryException(Skelta.Core.DS.SeverityLevel.Information, "User does not have a role assigned", new Skelta.Core.ApplicationObject(RepositoryName));

}

else

{

throw new Workflow.NET.ActiveDirectoryException(Skelta.Core.DS.SeverityLevel.Information, "Error while retrieving roles for the user" + ex.Message, new Skelta.Core.ApplicationObject(RepositoryName));

}

}

return StrRolesForUserArray;

}

/// <summary>

/// Checks if the user belongs to a specific role.

/// </summary>

/// <param name="resource">User object</param>

/// <param name="roleName">Role name</param>

/// <returns></returns>

public bool IsUserInRole(Workflow.NET.Resource resource, string roleName)

{

bool isGroupMember = false;

try

{

using (DirectoryEntry entry = new DirectoryEntry(_LDAPConnectionString))

{

DirectorySearcher deSearch = new DirectorySearcher();

deSearch.SearchRoot = entry;

deSearch.Filter = "(&(objectClass=group) (cn=" + roleName + "))";

SearchResultCollection results = deSearch.FindAll();

if (results.Count > 0)

{

DirectoryEntry group = null;

try

{

group = GetDirectoryEntry(results[0].Path);

object members = group.Invoke("Members", null);

foreach (object member in (IEnumerable)members)

{

DirectoryEntry x = null;

try

{

x = new DirectoryEntry(member);

if (x.Properties[EntityItemProperties.Identifier.PropertyName].Value.ToString().ToLowerInvariant() == resource.Properties.Identifier.Value.ToString().ToLowerInvariant())

{

isGroupMember = true;

break;

}

}

catch (Exception e)

{

throw e;

}

finally

{

if (x != null)

{

x.Close();

x.Dispose();

}

}

}

}

catch (Exception e)

{

throw e;

}

}

}

}

catch (Exception ex)

{

log.LogInformation("Error while checking user from role (" + roleName + ") for domain(" + _ConnectionString + ")" + ex.Message);

}

return isGroupMember;

}

/// <summary>

/// Verify whether role exists in the sql provider

/// </summary>

/// <param name="roleName">role name </param>

/// <returns></returns>

public bool RoleExists(string roleName)

{

bool CheckRoleStatus = false;

if (_IsConnectionValid)

{

string StrRoleName = roleName;

string StrSQl = "SELECT distinct role FROM users WHERE role =@role";

IDataHandler dbHandler = DataHandlerFactory.GetDataHandler(this._SQLConnectionString, "sql server");

System.Data.IDataReader idrRoles;

if (!string.IsNullOrEmpty(StrRoleName))

{

using (dbHandler)

{

System.Data.IDataParameter iparmRole = dbHandler.GetParameter("@role", roleName);

idrRoles = dbHandler.ExecuteReader(StrSQl, iparmRole);

while (idrRoles.Read())

{

CheckRoleStatus = true;

}

idrRoles.Close();

}

}

}

return CheckRoleStatus;

}

#endregion

#region ISkeltaAddInProvider Members

Guid _Id = Guid.Empty;

string _Settings = "";

Guid ISkeltaAddInProvider.Id

{

get { return _Id; }

}

//Initializing the provider

void ISkeltaAddInProvider.InitializeProvider(string settings, Guid id)

{

_Id = id;

_Settings = settings;

}

string ISkeltaAddInProvider.Settings

{

get { return _Settings; }

}

#endregion

#region "DataSourceProviderBase"

/// <summary>

/// Initializing the preferences [ReferralChasing,SearchScope,SizeLimit, LDAPBaseFilter] of Active directory

/// </summary>

/// <param name="definitionXml"></param>

public override void Initialize(string definitionXml)

{

try

{

XmlDocument xDoc;

xDoc = new XmlDocument();

try

{

xDoc.Load(new StringReader(definitionXml));

}

catch (System.Exception ex)

{

logger.LogError(ex, "Could not open the document ()");

throw ex;

}

//Get connection string

try

{

XmlNode xnc = xDoc.GetElementsByTagName("datasource").Item(0);

_SQLConnectionString = xnc.InnerText;

sDataSourceType = "sql server";

_IsConnectionValid = true;

if (string.IsNullOrEmpty(_LDAPServer))

{

XmlPropertyHandler xmlHandler = new XmlPropertyHandler(definitionXml);

_SearchScope = xmlHandler.GetSearchScope();

_ReferralChasing = xmlHandler.GetReferralChasing();

_SizeLimit = xmlHandler.GetSizeLimit();

_TimeOut = xmlHandler.GetTimeOut();

//_UserID = xmlHandler.GetUserID();

// _Password = xmlHandler.GetPassword();

_LDAPBaseFilter = xmlHandler.GetBaseFilter();

_LDAPSearchBase = xmlHandler.GetLDAPSearchBase();

_LDAPServer = xmlHandler.GetLDAPServer();

_ProviderPrefix = xmlHandler.GetDomainName();

if (!string.IsNullOrEmpty(_LDAPSearchBase)

&& string.IsNullOrEmpty(_ProviderPrefix))

_ProviderPrefix = _LDAPSearchBase.Split(',')[0].Split('=')[1] + "\\";

_IsPasswordEncrypted = xmlHandler.IsPasswordEncrypted();

_LDAPConnectionString = _LDAPServer + _LDAPSearchBase;

}

}

catch (System.Exception ex)

{

logger.LogError(ex, "Cannot get required information.");

throw ex;

}

}

catch (Exception ex)

{

logger.LogError(ex, "@@SkeltaMembershipDataProvider@Initialize");

throw ex;

}

}

internal delegate string GetDistiguisedNameFromCommonNameHandler(string CN);

internal class QueryToSearchFilterConversion

{

Hashtable Expressions = new Hashtable();

Hashtable Brackets = new Hashtable();

ArrayList BracketsArray = new ArrayList();

public string Output = "";

private Hashtable ParamHashTable = new Hashtable();

}

public override IEntityDataSourceProvider Clone()

{

//Clone the instance

Roles roleProvider = new Roles();

roleProvider = this;

return roleProvider;

}

/// <summary>

/// GetEntityItem is the only interface method of IEntityDataSourceProvider which will be used. This method call is initiated after Role is selected from UI and the virtual id for the role gets created.

/// This method does not get called while listing different roles for the provider.

/// </summary>

/// <param name="entityItemId"></param>

/// <returns></returns>

public override EntityItem GetEntityItem(object entityItemId)

{

string Identifier = EntityItemProperties.Identifier.PropertyName;

//It's role provider, so return single property value

EntityItemPropertiesCollection tempResProperties = EntityItemProperties.CreateDeepClone();

EntityItem entityItem = new EntityItem();

//We need to consider role itself as unique identifier.

tempResProperties[Identifier].Values.Add(entityItemId);

if (!string.IsNullOrEmpty(ProviderPrefix))

entityItemId = entityItemId.ToString().Replace(ProviderPrefix, "");

//It's mandatory for the role provider to perisist the RoleName in db, if a property named RoleName is not

//specfified or coded to be perissted in DB then the below code can be used to add or set the same

if (!tempResProperties.ContainsKey("RoleName"))

{

EntityItemProperty roleProperty = new EntityItemProperty();

roleProperty.PropertyName = "RoleName";

roleProperty.PropertyDisplayName = "Role";

roleProperty.PersistColumn = "RoleName";

roleProperty.Persist = true;

tempResProperties.Add(roleProperty.PropertyName, roleProperty);

}

else

{

tempResProperties["RoleName"].PersistColumn = "RoleName";

tempResProperties["RoleName"].Persist = true;

}

tempResProperties["RoleName"].Values.Add(entityItemId);

entityItem.Properties = tempResProperties;

return entityItem;

}

#endregion

}

}

Table Configuration:

Roles Database:

The roles database used in this example, has a single table called Users, which uses a column "Role" to assign/identify roles for the users.

Configuring custom roles involves entries in three tables of Skelta Repository database, namely:

  1. SKAddInProviders

  2. SKEntity

  3. SKEntityDataSourceProvider

The order and the detailed steps of configuration is listed below:

In the SKAddInProvider insert a new record with the following field values:

Column Name 

Value

ID

Auto Generated

Type

Roles

Name

Name for the Custom roles 

Description

Any description / Null

ClassName

Name of the class implementing 

Assembly

Path of the DLL built.

IsGacAssembly

False

Isdefault

False

LastUpdatedDateTime

Date time value

Example

Insert into SKAddInProviders (Type,Name,Description,ClassName,Assembly,IsGacAssembly,Isdefault,LastUpdatedDateTime)VALUES('Role','NewRoles','try mapping','NewRoles.Roles','bin\NewRoles.dll','False','False','5/12/2008 7:01:01 AM')

  1. Open the SKEntity table. No entries are required. Copy the Entity table "Id" column value of the RoleEntity row , for the entry to be made in SKEntityDataSourceProvider table.

  2. Open the SKEntityDataSourceProvider table, you will have a row with the default user provider "activedirectory". Now insert a new entry for our custom roles as defined.

    Column

    Value

    ID        

    Auto generated

    Application

    Name of the Repository

    Entity ID

    Copy the Id Column value of SKEntity of RoleEntity row here.

    DisplayName

    Forms

    DefinitionXML

    The definition xml should have details related to both sql provider and Active directory.

    for example, in the following definition xml the data source

    <dataproviders><provider name="sqlprovider" type="sql server"><properties><property         name="role" type="string" displayname="Role" purpose="identifier"/></properties><datasource>Data Source=SKELTADTP38;Initial Catalog=DS3;Integrated Security=True</datasource><Preferences><SearchScope>SubTree</SearchScope><ReferralChasing>External</ReferralChasing><TimeOut>60</TimeOut><SizeLimit>0</SizeLimit><AuthenticationUser></AuthenticationUser><AuthenticationPassword ></AuthenticationPassword></Preferences><LDAPServer>LDAP://</LDAPServer><LDAPSearchBase>DC=skelta,DC=dom</LDAPSearchBase><LDAPBaseFilter>(objectCategory=Person)</LDAPBaseFilter><DomainName>SKELTA\</DomainName></provider></dataproviders>

    Provider

    column must have the same name given in the "Name" column of SKAddInProviders table.

    Instance  Name

    activedirectory

    Example:

    insert into SKEntityDataSourceProvider(Application,EntityID,DisplayName,DefinitionXML,Provider,InstanceName) VALUES('ADSQLRep','69b60890-c24d-4ae5-8f03-cdd709a50d17','Forms','<dataproviders><provider name="sqlprovider" type="sql server"><properties><property name="role" type="string" displayname="Role" purpose="identifier"/></properties><datasource>Data Source=SKELTADTP38;Initial Catalog=DS3;Integrated Security=True</datasource><Preferences><SearchScope>SubTree</SearchScope><ReferralChasing>External</ReferralChasing><TimeOut>60</TimeOut><SizeLimit>0</SizeLimit><AuthenticationUser></AuthenticationUser><AuthenticationPassword ></AuthenticationPassword></Preferences><LDAPServer>LDAP://</LDAPServer><LDAPSearchBase>DC=skelta,DC=dom</LDAPSearchBase><LDAPBaseFilter>(objectCategory=Person)</LDAPBaseFilter><DomainName>SKELTA\</DomainName></provider></dataproviders>','NewRoles','activedirectory').

    • In the SKEntityDatasourceProvider table, every repository will have two entries. One with the display name "user provider name" for example, "activedirectory" and the other with the "user provider role" for example, "Active Directory role". Delete the row corresponding to the display name " Active Directory role". This is done to avoid the roles to be listed in the Enterprise Console from the active directory.

    The Classes and Interfaces that need to be used to implement Custom Roles in AVEVA Work Tasks are:

    1. The Custom Roles Class has to be derived over "DataSourceProviderBase" part of Skelta.Entity namespace.

    2. The Interface to be implemented by the Custom roles are:

      1. IRoleEntityDataSourceProvider – [Skelta.Entity.RoleEntityProvider]

      2. ISkeltaAddInProvider – [Skelta.Core]

      Key Methods and Properties:

      IRoleEntityDataSourceProvider Members

      1. public string IRoleEntityDataSourceProvider.EntityIdentifierType() - This property returns the "identifier" type for the resources, which is "string" by default.

      2. void IRoleEntityDataSourceProvider.Initialize() - This method is used to initialize the XML definition of the roles entity.

        ISkeltaAddInProvider Members

        1. Guid ISkeltaAddInProvider.Id - This property returns the AddInProviderId of the default role provider.

        2. void ISkeltaAddInProvider.InitializeProvider(string settings, Guid id) - This method is used to initialize the provider.

          DataSourceProviderBase Class Members

          1. public override void Initialize(string definitionXml) - This method reads the XML definition.

          2. public override EntityItem GetEntityItem(object entityId) - This returns the entity type, which is role and returns single property value.

            After defining the methods and the properties as per the custom roles definition being used, build the project that generates <custom roles name>. DLL. This DLL needs to be now copied to the AVEVA Work Tasks bin folder.

            Troubleshooting

            You will get the "Object reference not set to an instance of an object" error when you try to open the Enterprise Console. One of the reason for this could be the access to the assembly path [that you have mentioned in the SKAddInProviders tables] is denied. To avoid this:

            1. Copy the dll ( NewRoles.dll ) which you have created and put it in the folder where you have full access.

            2. In SKAddInProviders table's Assembly column, update the assembly path.

              Example:

              1. If your dll is in C:\, then in the Assembly column of the SKAddInProviders table, update the url as C:\NewRoles.dll.

              2. If your dll is in D:\Sample, then in the Assembly column of the SKAddInProviders table, update the url as D:\Sample\NewRoles.dll.

                TitleResults for “How to create a CRG?”Also Available in