I have a simple structure of the users like this:
public Guest() : IUser
{
}
[Table("Users")]
public class Customer : Guest
{
[Key]
public string UserName { get; set; }
public string Password { get; set; }
public string Address { get; set; }
public bool IsAdmin { get;protected set; }
public UserCart UserCart { get; private set; }
public Customer()
{
}
public Customer(string username, string password, string address)
{
this.Address = address;
this.UserName = username;
this.Password = password;
this.IsAdmin = false;
this.UserCart = new UserCart();
}
}
public class Admin : Customer
{
public Admin()
{
}
public Admin(string username, string password,
string address)
: base(username, password, address)
{
IsAdmin = true;
}
}
The inheritance is based on Actions they can do. The system will have to work differently depending on who uses it.
Admins can browse and buy and mess around with the orders and goods.
Customers can browse and buy.
Guests can browse only (and login/reg of course).
To know who's our current user, we need a property or field inside our Authentication class
that is IUser
, so anyone, an Admin, a Customer and a Guest can also be instantiated in it.
Problem is, when I have only this IUser, when I instantiate, I can do basically nothing.
So the question: I want to load that field or property and I still want to access the functionalities of it - but only those that the given user can, so if an Admin logged in, I want to do the admin's job. If a Customer logged in, I want only to be able to list the goods and so on. How to do this?
EDIT: trying with reflection
public class Guest : IUser
{
public Guest()
{
}
public object Get()
{
Type type = this.GetType();
var result = Activator.CreateInstance(type);
return result;
}
}
That Get()
method gives only an object
but if it is called by a Guest
, it has to be Guest. If called by an Admin
, it has to be Admin.
I could do this using overrides, but it's hard to modify later on.
So I wish this:
(MyObject)Activator.CreateInstance(type);
Where MyObject
is a Guest if called from a Guest, Admin if called from an admin. What am I missing? of course I tried generics, but that expects a concrete type when I'm implementing the interface, so basically I need to implement this in all my descendant classes.
Based on what we talked in the comments, here is a direct copy paste form our server-side game code. But a reminder to keep in mind: If you define IUser
interface but always cast it into appropriate class later like var customer = iUser as Customer
. you may be on the wrong path. We use the below code only on a few occasions.
public void DoSomethingWithBattleUnit(BattleUnit bUnit){
if(bUnit.UnitType==typeof(BattleMonster)){
var bMonster = bUnit as BattleMonster;
bMonster.ActivateAI();
}
public abstract class BattleUnit {
public abstract Type UnitType { get; }
}
public class BattleMonster : BattleUnit {
/// <summary>
/// Current type for this class.
/// </summary>
/// <remarks>Micro optimization instead of using this.GetType() or calling typeof(BattleMonster) each time.</remarks>
static readonly Type Type = typeof(BattleMonster);
public override Type UnitType => Type;
}
public class BattleUser : BattleUnit, IUser {
/// <summary>
/// Current type for this class.
/// </summary>
/// <remarks>Micro optimization instead of using this.GetType() or calling typeof(BattleUser) each time.</remarks>
private static readonly Type Type = typeof(BattleUser);
public override Type UnitType => Type;
}