A quick follow up about data restrictions
A comment on my last post caused me to re-read it, and realize that I didn’t do a good job of emphasizing the role of data restrictions (implementations of IDataRestriction<T>
) in our application. Since I introduced them in the context of the RestrictedQuery
method on our Repository class, it gave the impression that they were just helpers for data access. The reality is that RestrictedQuery was actually a usage we discovered very late in the design of data restrictions. The data restriction classes simply encapsulate rules for determining access to an entity.
The key to its flexibility is the IDataSourceFilter<T>
parameter passed to the data restriction at runtime. For a quick reminder, look at the implementation of the “sensitive case” data restriction:
public class SensitiveCaseDataRestriction : IDataRestriction<Case> { public void Apply(IDataSourceFilter<Case> filter) { if (!PrincipalRoles.IsInRole(DomainActions.ViewSensitiveCases)) { filter.WhereEqual(x => x.IsSensitive, false); } } }
The data restriction performs actions on the filter passed to it. What effect that filter ultimately has on the system is not known, nor a concern of the data restriction itself. That is the role of the data restriction consumer, who determines which type of implementation of IDataSourceFilter
The bottom line is that data restrictions represent behavior of the domain (like “only users with the “view sensistive cases” privilege should see cases marked as sensitive”), and live in the domain. The fact that we were able to easily leverage these rules in our data access code is a pleasant bonus.