Implementacja interfejsu - czegoś brakuje, czy idę w złą stronę

0

Mam sobie metodę generyczną, która działa na ...TCar ... where TCar : ICar, new(). W metodzie tej tworzę instancję w ten sposób TCar car = new TCar() { ... }. Ale do tej metody potrzebuję przekazać coś co implementuje ICar. No i tu jest problem, bo taka konstrukcja jak poniżej daje błąd:

    public class Car : ICar
    {
        public Wheel Wheel { get; set; }
    }

    public interface ICar
    {
        IWheel Wheel { get; set; }
    }

    public class Wheel : IWheel
    {

    }

    public interface IWheel
    {

    }
'Car' does not implement interface member 'ICar.Wheel'. 'Car.Wheel' cannot implement 'ICar.Wheel' because it does not have the matching return type of 'IWheel'.

Wie ktoś jak to rozgryźć?

1

Sygnatury funkcji nie zgadzają się. IWheel nie Wheel

    public class Car : ICar
    {
        public IWheel Wheel { get; set; }
    }
0

Takie rozwiązanie z SO dostałem, trochę brzydkie, ale robi robotę:

public class Car : ICar
{
    public Wheel Wheel { get; set; }

    IWheel ICar.Wheel
    {
        get { return Wheel; }
        set { Wheel = (Wheel)value; }
    }
}
0

bo Entity Framework

Według mnie XY problem.

1

Ale po co tak konkretnie te interfejsy w warstwie składowania danych?

0

Mam 4 podobne klasy dot. postów i robię wysyłanie powiadomień z nimi związanych, nazwijmy je PostA, PostB, PostC, PostD.

Dla powiadomień mam też 4 oddzielne klasy, różnią się one tylko tym do jakiej encji odwołuje się Id.
NotificationA : BaseNotification<PostA> {}, NotificationB : BaseNotification<PostB> {}...

W BaseNotification BaseNotification<T> where T : IPost i w ciele T RelativePost {get; set; }.

W klasie NotificationsService mam metodę SendNotification<TPost, TNotification>(TPost post ...) where TPost : IPost, żeby ją wywołać to piszę np.notificationService.SendNotification<PostB, NotifcationB>(postB...) gdzie postB jest instancją klasy PostB, która implementuje interfejs IPost.

Edit: A no i najważniejsze: BaseNotification implementuje INotification, który narzuca posiadanie IPost

Możliwe, że nie jest to najlepsze podejście, ale nie wpadłem na lepszy pomysł.

1

Czyli masz jakąś logikę biznesową - wysyłanie powiadomień. I do realizacji tej logiki biznesowej zamiast klas z warstwy logiki biznesowej chcesz używać klas z warstwy składowania danych. I tu powstaje problem, bo warstwa składowania danych opiera się o ORM, który nakłada pewne ograniczenia czy wymogi i sprawia, że nie możesz pisać w czystym C#, tylko zgodnie z wymaganiami ORMa.

Więc opcje masz takie, że albo jakiś hack (jak to zrobiłeś z jawną implementacją interfejsu) albo stworzenie warstwy logiki biznesowej oddzielnej od warstwy składowania.

0

Czyli modele powinny mieć swoje odpowiedniki w warstwie logiki? No to muszę sobie zrobić rekonesans, bo nie napotkałem takiego rozwiązania. Mają one jakąś konwencje nazewniczą, tak jak w warstwie prezentacji jest to suffix DTO?

2

Logika biznesowa to jest model dziedziny (domeny), to powinny być klasy niezależne od jakiegokolwiek frameworka/biblioteki/orma czy czegokolwiek innego. Dopiero gdy potrzebujesz je gdzieś przechowywać tworzysz sobie warstwę do przechowywania danych, w której możesz np. użyć ORMa, który będzie wymagał swoich oddzielnych klas. No chyba, że będzie mądry i będzie umiał przechowywać model domeny, ale nie wszystkie takie są. Ale generalnie kierunek projektowania powinien wychodzić od domeny do składowania, a nie odwrotnie.
Podział aplikacji na oddzielne warstwy według odpowiedzialności nazywa się w ogólności architektura.

Co do sufiksu, to chyba więcej sensu ma nadanie go klasom z warstwy składowania niż tym z domeny.

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