For developers: Dynamic modules permissions on multiple providers
You use providers to manage the data representation of items of specific types on a specific data source. A data source can be a database, file, REST API, etc.
You use multiple providers for items of the same type in order to adapt data from different data sources (multiple databases) or to separate data when more than one provider is using the same data source (multiple providers). Using the multiple databases pattern requires using multiple providers.
To understand the usage of multiple providers in dynamic modules, you must be familiar with the structure and the inheritance of the permissions. For more about this see Overview: Permissions.
Depending on whether you use the default or non-default dynamic module provider, there are different structures for storing and manipulating permissions for a dynamic content, dynamic type, or the dynamic module itself. For different dynamic module providers you can assigning different permissions for dynamic modules, dynamic types, and dynamic content items and fields.
Dynamic modules and the dynamic types are secured objects, which implement the ISecuredObject interface. This means they can be assigned permissions on their Permissions collection. Because each dynamic module or type can holds only one collection of permissions, Sitefinity CMS stores permissions only for the default dynamic module provider.
In cases where you add a second non-default dynamic module provider, Sitefinity CMS creates additional objects that hold Permissions collections on module, type, and field levels. These additional objects are called DynamicContentProviders (DCP). They implement the role of permission holders for the current dynamic module provider on the respective level (module, type, and field).
The DCPs follow the same permission inheritance as the main secured object that they emulate ModuleBuilderProvider » Module » Type and, respectively, ModuleBuilderProvider » Module DCP » Type DCP. DCP for fields is not a member of the permissions hierarchy. It only holds the permissions for the current field for the specific DynamicModuleProvider.
To obtain those permissions holders is done by invoking the GetSecuredObject(ISecuredObject, ProviderName) method as in the following example:
ISecuredObject securedObject = manager.GetSecuredObject(mainSecuredObject, dynamicDataProviderName);
if (securedObject == null)
{
lock (DynamicPermissionHelper.secRootLockObject)
{
securedObject = manager.GetSecuredObject(mainSecuredObject, dynamicDataProviderName);
if (securedObject == null)
{
securedObject = manager.CreateSecuredObject(mainSecuredObject, dynamicDataProviderName);
if (manager.TransactionName.IsNullOrEmpty())
{
manager.SaveChanges();
}
}
}
}
In the above example, mainSecuredObject can be a dynamic module, a dynamic module type, or a field. The dynamicDataProviderName is the name of the DynamicModuleProvider for which you want to retrieve the DCP (permissions holder). The manager is the ModuleBuilderManager instance and the securedObject is the retrieved DCP. If the manager cannot obtain the secured object by dynamic data provider name, it will creates the security object for the given object for the first parameter.
NOTE: If you use the default provider, the securedObject is the mainSecuredObject. Similarly, if the dynamicDataProviderName is the name of a non-default provider, the securedObject will be the DCP (permission holder,) which corresponds to the mainSecuredObject for that non-default provider.