Реализация типов безопасных потоков активности в C # - PullRequest
0 голосов
/ 17 октября 2018

Я заинтересован в реализации типизированного потока операций (стандарт определен здесь ), где мой бэкэнд - Azure CosmosDB.Постановка проблемы заключается в следующем.

Я использую общий репозиторий CosmosDB для хранения всех своих действий.Я использую одну коллекцию для хранения всех сущностей, поэтому я создал CosmosDBRepository, который преобразует доменные объекты в объекты данных, и в процессе добавляет поле Type, которое соответствует имени класса.Таким образом, я могу использовать одну коллекцию для ссылки на множество различных типов документов.Я использую Automapper, чтобы отобразить объекты данных на объекты домена и убедиться, что объекты данных никогда не покидают слой хранилища.Итак, каждый сервис, который использует мои репозитории, использует объекты домена вместо объектов данных.Это прекрасно работает для всех обычных классов.Теперь мне нужно реализовать класс Activity из спецификации Activity Stream, и мне нужно сгенерировать json, который учитывает различных субъектов, объекты, цели и глаголы, как показано в ссылке на спецификацию стандартов.

Сложность возникает в моем решении реализовать Activity как общий класс.Вот моя реализация

public class Activity<A, O, T, V>: AggregateRoot
        where A : AggregateRoot
        where O : AggregateRoot
        where T : AggregateRoot
        where V : ValueObject<V>
    {
        // todo: This will allow the user to create derived classes with the 
        // wrong verbs. Figure out how to not allow that yet support a builder pattern
        public Activity(V v) : base() => Action = v;
        public A Actor { get; set; }
        public O Object { get; set; }
        public T Target { get; set; }
        public V Action { get; protected set; }
        public string ActivityType { get => this.GetType().Name; private set { } } // This is the type name of the concrete activity e.g. "UserLikesItemInRoom"

        // This is where reaction activities store their additional content

        public AdditionalContent Content { get; set; }
    }

Мой объект домена выглядит следующим образом

public class UserLikesItemInRoom: Activity<User, Item, Room, Like>
{
    public UserLikesItemInRoom(User user, Item item, Room, room)
         : base(user, item, room, "like") // 
    {
    }
}

Существует много таких классов, как этот.UserShareItemToFacebookFeed и т. Д. И т. Д. И т. Д. И т. П. Каждый имеет свой тип Actor, Object и Verb.Я определил несколько сопоставителей между каждым из этих классов и классом ActivityDO, который является объектом данных, в который все сериализуется.

Когда я получаю действия, это набор из множества разных классов без общего интерфейса.Итак, у меня есть эти вопросы дизайна.

  1. Обречено ли решение о внедрении Activity как универсального обреченного на неудачу?
  2. В такой конфигурации, каков наилучший способ получить список действий, для которых возвращенная коллекция имеетнесопоставимые классы, полученные из одного и того же родовогоДолжен ли я реализовать интерфейс маркеров для всех действий?
  3. Лучше ли вообще не использовать шаблоны и использовать интерфейсы маркеров IActor, IObject и ITarget?
  4. Как сделатьЯ сериализирую вход и выход из Cosmos DB, используя один репозиторий, а не репозиторий для каждого производного от общего типа (например, UserLikesItemInRoom, UserPinsItemInRoom и т. Д.)?
...