ContentDecorator for third party ORM
[ContentProviderDecorator(typeof(OpenAccessContentDecorator))]
public class OpenAccessJobsDataProvider : JobsDataProviderBase, IOpenAccessDataProvider
Hello Larry,
You can use another ORM instead of OpenAccess inside Sitefinity for custom implementations like custom modules that are not based on one of the built-in modules, controls that does not inherit from our bases classes which relies on a wcf services which manager classes use built-in OpenAccess data provider.
Sitefinity 4.0 is not tightly integrated with OpenAccess ORM. You can replace some of the built-in data classes with custom one( which is not a trivial task). For instance you can create a custom data class that inherits from PageDataProvider. PageDataProvider is abstract class and our OpenAccessPageProvider inherits from it. It also depends on whether your data layer supports POCO objects - objects that are not tied to a specific context.
Kind regards,
Ivan Dimitrov
the Telerik team
I fully understand now.
However, I would like to know what does 'ContentProviderDecorator' does? The Document doesn't talk about it...
If I were to develop a custom module, is it necessary? What purpose does it solve?
I was thinking about the same thing too. Any ideas?
Hello ,
Decorators are a way of sharing implementation accross multiple data providers.
Best wishes,So, If I have to use NHibernate, do I need to write NHibernateContentDecorator?
If so, what methods should I implement? Do u have a sample for that?
One sentence answers only create frustation.... They don't help in any way.... Can you please be little more clear? I want a direction, because I am seriously considering another ORM vendor... I can't use design mode for Open Access in Sitefinity (because of custom build and I don't want to be struck with a certain version ) and I am evaluating XPO/LLBLGenPro to create custom modules.....
Hello Larry,
If you write custom providers that make use of another ORM, you don't have to write a decorator. The decorator that we have implemented is mostly containing some shared logic between our content data providers(for example the comments manipulation logic). You can implement this logic inside your provider entirely without implementing a decorator. The decorator will be useful if you have many providers and want to share a common implementation between them. If you inherit ContentDataProviderBase, you will have to override all methods that are related to working with comments, since they make use of this ContentDecorator.
All the best,
Nikolay Datchev
the Telerik team
Hi Nikolay,
How about implementing GetSecurityRoot() method for custom data provider that does not inherit from ContentDataProviderBase? I found that Sitefinity stores security roots in the sf_security_roots table.
As far as I understand, it checks before, if the security roots exist for the appropriate data provider. If they don't exist then SetRootPermissions method of data provider will be executed.
I can't figure out how I can check for existing security roots. Can you provide an example how to select the security roots for custom data provider?
Thanks in advance,
Anton.
Hi Larry,
This the actual implementation of this method that our providers use is in the OpenAccessDecorator. Generally we have a security root implementation for OpenAccess based providers and this is the code:
BTW (DataProvider property here should be your custom provider. Context is the the OpenAccessContext that is used work with Open Access persisteny objects)
/// <returns></returns>
public SecurityRoot GetSecurityRoot()
var secObj = this.DataProvider as ISecuredObject;
if (secObj != null && secObj.Id != Guid.Empty)
// Always use this method. Do NOT change it to query. Catch the exception if the Id can be wrong.
var root = this.Context.GetItemById<SecurityRoot>(secObj.Id.ToString());
return root;
return null;
/// <summary>
/// Gets the security root.
/// </summary>
/// <param name="create">if set to <c>true</c> a security root will be created for the provider if there is no root.</param>
/// <returns></returns>
public SecurityRoot GetSecurityRoot(bool create)
return this.GetSecurityRoot(create, new Dictionary<string, string>(), new string[] );
/// <returns></returns>
public SecurityRoot GetSecurityRoot(bool create, IDictionary<string, string> permissionsetObjectTitleResKeys, params string[] permissionSets)
var secObj = this.DataProvider as ISecuredObject;
if (secObj != null)
var appName = this.DataProvider.ApplicationName;
var key = String.Concat(this.DataProvider.RootKey, this.DataProvider.Name);
var root = this.Context
.GetAll<SecurityRoot>()
.Where(r => r.ApplicationName == appName && r.Key == key)
.FirstOrDefault();
if (root == null && create)
if (permissionSets.Count() == 0)
root = new SecurityRoot(appName, Guid.NewGuid()) Key = key ;
else
root = new SecurityRoot(appName, Guid.NewGuid(), permissionSets, permissionsetObjectTitleResKeys) Key = key ;
this.Context.Add(root);
this.DataProvider.SupportedPermissionSets = permissionSets;
var orgVal = this.DataProvider.SuppressSecurityChecks;
this.DataProvider.SuppressSecurityChecks = true;
this.DataProvider.SetRootPermissions(root);
this.DataProvider.SuppressSecurityChecks = orgVal;
this.CommitTransaction();
CacheDependency.Notify(new object[] root );
return root;
return null;
Kind regards,
Nikolay Datchev
the Telerik team