C # Интерфейсные правила для возвращаемых типов данных - PullRequest
0 голосов
/ 15 февраля 2019

Я занимаюсь разработкой приложения на C #, которое представляет собой интерфейс, который может принимать или возвращать данные различным внешним приложениям / клиентам через (скорее всего) REST API.Приложение должно быть разработано достаточно гибко, чтобы внутреннее хранилище данных могло быть заменено только изменением файла конфигурации, чтобы указывать на новое хранилище данных или, возможно, циклически перебирать доступные хранилища данных, чтобы найти данные в хранилищах данных различного формата.Общая структура данных - это примерно файловая система / дерево с пользовательскими данными, прикрепленными к некоторым узлам для поиска, разрешений и т. Д.

Например, мы могли бы иметь живые производственные данные в SQLБД, но есть вероятность, что некоторые унаследованные данные будут храниться в плоских csv-файлах на сетевом ресурсе, и есть желание включить новые реализации интерфейса в будущем (их реализация в базе данных уже была бы определена,это означает, что если что-то имеет pkid типа GUID, мы не можем это изменить.)

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

public long CreateFolder(long parent, string folderName);

, который бы отлично работал для чего-то, использующего целочисленные или длинные идентификаторы, но у потребителя реализации интерфейса были бы проблемы, если бы возвращением действия CreateFolder было руководствоили имя файла (строка).Желание также состоит в том, чтобы как можно меньше изменить уровень «бизнес-логики» и внести изменения на уровне данных самого низкого уровня.

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

Есть какие-нибудь указания на что-то подобное?

РЕДАКТИРОВАТЬ: Чтобы добавить это шаблон, который я использую для интерфейсов БД.

https://softwareengineering.stackexchange.com/questions/301362/how-are-abstract-database-interfaces-written-to-support-multiple-database-types/301371

Сейчас я склоняюсь к перегрузке всех интерфейсов string, int и long, а затем обрабатываю приведение / преобразование в реализации интерфейса.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Требования:

  1. Есть возможность хранить / получать данные в разных источниках
  2. Простота изменения соединения, что использовать.

Решение:

Я думаю, что в вашем случае будет хорошо использовать шаблон Repository и некоторые Fabric, которые решили, какой репозиторий использовать.Кроме того, вы можете создать репозиторий как универсальный, чтобы иметь возможность быстро менять модель для работы.

public class IRepository<T> where T : class
{
   T Save(T model);
   IEnumerable<T> Get(Expression... condition);
   //another methods.
}

DbRepository<T> :IRepository<T>
{
}
CsvRepository<T> :IRepository<T>
{
}
0 голосов
/ 15 февраля 2019

Я предлагаю вам возможное решение:

public abstract class AbstractController<T> : ApiController {
    [HttpPost] // Or GET
    [Route("createfolder")]
    public IHttpActionResult CreateFolder<T>(long parent, string foldername) {
        T result = YourClass.CreateFolder<T>(parent, foldername);

        return Ok(result);
    }
}

[RoutePrefix("api/sql")]
public abstract class SqlController : AbstractController<long> { }

[RoutePrefix("api/csv")]
public abstract class SqlController : AbstractController<string> { }

Возможно ли это?

0 голосов
/ 15 февраля 2019

Вы должны абстрагироваться от различий.В самом простом случае измените подпись на:

public IFolder CreateFolder(long parent, string folderName);

Определите IFolder как интерфейс C # следующим образом:

public interface IFolder { // Example method to be implemented by inheritors. void EnumerateFiles(); }

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...