Restricting Access to Properties in NHibernate
Update: unlike what I always thought, "protected internal" means "protected" OR "internal", so this technique is really not that necessary. Thanks to all the commenters who brought that to my attention!
One common requirement is that internal properties of a class can be accessed from other classes on the same assembly. Using NHibernate, you generally cannot use private or internal properties, unless you don’t need to use lazy loading. That is because the NHibernate proxy generator creates dynamically a class for each of your lazy entities, and it does this by subclassing them. The generated classes exist in another assembly, and private and internal properties cannot be accessed from outside the class/assembly on which they are declared.
One solution for this problem is to use internal interfaces for exposing these properties to the same assembly. Consider this example:
1: public class MyEntity
2: {
3: public virtual Int32 SensitiveProperty
4: {
5: get;
6: protected set;
7: }
8: }
As you can see, the SensitiveProperty can be publicly read but can only be changed from inside the MyEntity class or one inherited from it.
Let’s introduce an internal interface:
1: interface ISecureModifiable
2: {
3: Int32 SensitiveProperty
4: {
5: get;
6: set;
7: }
8: }
We need to refactor MyEntity so as to realize this interface:
1: public class MyEntity
2: {
3: public virtual Int32 SensitiveProperty
4: {
5: get;
6: protected set;
7: }
8:
9: Int32 ISecureModifiable.SensitiveProperty
10: {
11: get
12: {
13: return(this.SensitiveProperty);
14: }
15: set
16: {
17: this.SensitiveProperty = value;
18: }
19: }
20: }
Now, all classes in the same assembly as MyEntity and ISecureModifiable can access the SensitiveProperty property, but no other class can – excluding reflection, of course:
1: MyEntity e = ...;
2: ISecureModifiable s = e as ISecureModifiable;
3: s.SensitiveProperty = 100;
Because the interface ISecureModifiable is internal to the assembly on which it is declared, it won’t even be visible from the outside.