.NET Polimorfizm użytkowników - rzutowanie w dół

0

Witam, tworzę pierwszy projekt do obsługi targów pracy i mam problem z polimorfizmem. Przede wszystkim chciałbym mieć klasę User z danymi do logowania oraz powiązaną do niej klasę UserProfile ze wszystkimi danymi. Problemem jest to, że w aplikacji potrzebuję dwóch typów użytkowników - moderatorów oraz zwykłych użytkowników powiązanych z firmą. Stworzyłem do tego klasę ModeratorProfile oraz CompanyProfile zawierające różne dane dziedziczących po UserProfile

User.cs

public class User : Entity
    {
        private static List<string> _roles = new List<string>
        {
            "user", "admin", "moderator"
        };
        public string Role { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public DateTime CreatedAt { get; set; }
        public UserProfile UserProfile { get; set; }
        public bool IsActive { get; set; } = false;
        public bool IsCompany { get; set; }
        public User(Guid id, string role, string email, string password, string name)
        {
            Id = id;
            Role = role;
            Email = email;
            Password = password;
            CreatedAt = DateTime.UtcNow;
            if (role == "user")
                SetCompanyName(name);
        }
        private void SetCompanyName(string name)
        {
            IsCompany = true;
            UserProfile = new CompanyProfile(name);
        }
    }

UserProfile.cs

public abstract class UserProfile : Entity
    {
        public Guid? UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int PhoneNumber { get; set; }
    }

CompanyProfile.cs

public class CompanyProfile : UserProfile
    {
        public string CompanyName { get; set; }
        public string CompanyStatus { get; set; }
        public string DayOfParticipation { get; set; }
        public IEnumerable<Answer> Answers { get; set; }
        public CompanyProfile(string name)
        {
            CompanyName = name;
            Id = Guid.NewGuid();
        }
    }

Czy takie rozwiązanie jest słuszne i każdy User będzie powiązany one-to-one z CompanyProfile lub ModeratorProfile przy użyciu EF?
Problemem jest również rzutowanie, ponieważ powyższe klasy są w projekcie Core, do którego nie mam odwołania w projekcie API więc przy pobieraniu GET otrzymuję wartości:

{
    "role": "user",
    "email": "email12",
    "password": "secret",
    "createdAt": "2020-04-19T22:14:06.2916052Z",
    "userProfile": {
        "userId": null,
        "firstName": null,
        "lastName": null,
        "phoneNumber": 0,
        "id": "135c9fce-ebfe-4a70-8aaf-811fa0f15c8c"
    },
    "isActive": false,
    "isCompany": true,
    "id": "99685b51-838c-4129-ac92-9c5347900a23"
}

W UserService pomiędzy API i Core nie pomaga

        public async Task<User> GetAsync(string email)
        {
            var user = await _userRepository.GetAsync(email);
            user.UserProfile = (CompanyProfile)user.UserProfile;
            return user;
        }

Jak mogę rzutować sekcję userProfile na CompanyProfile bez odwołania w Api?

3

Zwykły i Moderator / Admin to zwyczajowo we wszystkich językach nazywa się jako Rola (ang Role). Używasz tej nazwy - nie wiem, czy analizowałeś jakieś oprogramowanie

Co do Twojego projektu, to popełniasz MSZ błąd zbytnio dziedzicząc. Powszechnie się zaleca "Kompozycja zamiast dziedziczenia", do Twojego problemu pasuje idealnie.

Więc wracając do Roli: Użytkownik NIE JEST ROLĄ, ale Użytkownik POSIADA ROLE. Używam liczby mnogiej, tych ról może przybywać, więc w języku C# klasa Użytkownik ma publicznie udostępnić np property zwracające tablicę ról.
Lepsze będzie type-safe, czyli Role to oddzielna klasa, choć niewiele przewyższa string

Zobacz jakie to ma miłe efekty: można zostać adminem, albo przestać, zachowując tożsamość. W dodatku dziedziczenie stawia problemy do rozwiązania przy mapowaniu obiektowo-relacyjnym, tu (dodatkowych niepotrzebnych problemów) unikamy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1