I'm trying to encapsulate permissions logic for a particular view model in a way that the permission logic has access to the view model object, but is also exposed inside of it
Trivial Implementation:
public class ClientViewModel
{
public Client Client { get; set; }
/* permissions section */
public bool CanVote => Client.Age > 18
public bool CanDrink => Client.Age > 21
}
The implementation is pretty clean and simple. The view will need to make lots of decisions based on the set of properties available within the permissions. But there are going to be a lot of permissions so ideally I'd like to contain that logic somewhere else.
Right now I can access like this:
var vm= new ClientViewModel() { Client = myClient };
vm.CanVote
But I'd like to contain all the logic inside a single class and access like this:
vm.Permissions.CanVote
Circular Implementation
So I can put a property of type ClientViewModelPermissions on the ViewModel itself. It needs to have access to data objects on the ViewModel it's describing so I can pass in the instance of the model into the Permissions constructor and new it up during the construction of the model itself, like this:
public class ClientViewModel
{
public ClientViewModel()
{
// create instance of permissions for current object
Permissions = new ClientViewModelPermissions(this);
}
public Client Client { get; set; }
public ClientViewModelPermissions Permissions { get; set; }
}
public class ClientViewModelPermissions
{
public ClientViewModelPermissions(ClientViewModel clientVm)
{
// permissions must describe a particular view model
ClientModel = clientVm;
}
private ClientViewModel ClientModel { get; set; }
public bool CanVote => ClientModel.Client.Age > 18
public bool CanDrink => ClientModel.Client.Age > 21
}
So each class contains a reference to the other as a property. Should this be avoided for any reason? Is there a cleaner way to evaluate properties for a given class, but keep that logic separate than actual class itself by decorating it somehow?
Here's an image with the above code showing the flow of dependencies across classes.