Reputation: 12863
I have a generic type (RoleEntity) that may or may not implement an interface that is also generic (IActor). Background on the design is below, but the short story is that a RoleEntity is a role that maybe assumed by an Actor and that RoleEntity may optionally be an IActor with it's own Roles.
So if I want to access the Roles of a an Actor's role, I can think of two options
The code below is a bastardized mix of both. I am using reflection but not far enough to actually figure out the exact IActor{T}. Then because I have an indeterminate type I use IEnumerable{dynamic}. It doesn't feel like good code but I don't know how to do better.
Can someone present some cleaner code?
static void GetRoleHeirarchyString<T>(IActor<T> actor)
where T : Entity, IActor<T>
{
foreach (var role in actor.AllRoles) {
// do something with the Role;
// trivial reflection
var type = role.GetType();
var pi = type.GetProperty("AllRoles");
if (pi == null)
continue;
var roles = pi.GetValue(role, null) as IEnumerable<dynamic>; // dynamic
foreach (var r in roles) {
// do something with the Role;
}
}
}
Below are two interfaces that are part of a solution implementing Roles. In this design, a class that might be expressed as one or more Roles is called an Actor. The class that is expressing a Role (called a 'Role'!) uses an instance of the Actor to forward properties of interest from the Actor. So for example, if a Person class is an Actor for several roles in an application )ie, Student, Mother, and Employee) then each Role might use an instance of the Person to have a common Name property that is based on the Person.
Roles may or may not also be Actors; an Employee may be a ProjectManager or even a Buyer of something her employers sells. But a Student may just be a role for a Person and not an Actor.
public class RoleEntity<T> : Entity where T : Entity, IActor<T>
{
public T Actor { get; protected set; }
...
}
public interface IActor<T> where T : Entity, IActor<T>
{
bool AddRole(IRoleFor<T> role);
bool RemoveRole(IRoleFor<T> role);
bool HasRole(IRoleFor<T> role);
IEnumerable<IRoleFor<T>> AllRoles { get; }
}
Upvotes: 0
Views: 138
Reputation: 3834
Sometimes it is possible to define non-generic interface IRoleEntity
and have your RoleEntity<T>
implement IRoleEntity
.
If you declare a method IRole.DoSomethingWithTheRole, then you can implement it in RoleEntity<T>
.
And you can call it without knowing exact RoleEntity<T>
type thanks to polymorphism.
Same trick you may want to do with IActor<T>
inheriting IActor
.
It doesn't always make sense, but I don't have enough understanding of your problem.
Upvotes: 1