Интерфейс с 3 различными возвращаемыми значениями - PullRequest
0 голосов
/ 19 июня 2019

У меня есть служба поддержки клиентов для 6 разных магазинов с 3 разными API-системами для магазинов, поэтому в моем проекте есть 3 библиотеки

Как и

Shopsytem 1 -> (Lib1)
Shop A
Shop B
Shop C

Shopsystem 2 -> (Lib2)
Shop D
Shop E

Shosystem 3 -> (Lib3)
Shop F

У меня есть «Контроллер контактов» в Lib1,Lib2 / Lib3, унаследованный от Lib1

Теперь мне нужно вызвать функцию, подобную

contractService.getContracts();

С моим интерфейсом

public interface IContractService
{
    List<ContractData> GetContracts()
}

В каждой библиотеке Lib есть класс, подобный

public Shopsystem1ContractService : IContractService {   
    List<ContractData> GetContracts(){...}
}

public Shopsystem2Contractservice : IContractService {
    List<ContractData> GetContracts(){...}    
}

public Shopsystem3ContractService : IContractService {
    List<ContractData> GetContracts(){...}    
}

Но теперь мне нужно что-то вроде этого:

public Shopsystem1ContractService : IContractService {   
    List<Shopsystem1ContractData> GetContracts(){...}
}

public Shopsystem2ContractService : IContractService {
    List<Shopsystem2ContractData> GetContracts(){...}    
}

public Shopsystem3contractservice : IContractservice {
    List<Shopsystem3ContractData> GetContracts(){...}    
}

Обновление:

Теперь я использую универсальный интерфейс в соответствии с Юхарром и Юлиусом:

    interface IContractService<TContract> where TContract : ContractData
{
     List<TContract> GetContracts();
}

public Shopsystem1ContractService : IContractService<Shopsystem1ContractData>
{   
    List<Shopsystem1ContractData> GetContracts(){...}
}

public Shopsystem2ContractService : IContractService<Shopsystem2ContractData>
{
    List<Shopsystem2ContractData> GetContracts(){...}    
}

public Shopsystem3contractservice : IContractservice<Shopsystem3ContractData>
{
    List<Shopsystem3ContractData> GetContracts(){...}    
}

IoCModule:

    ioc.Register<IContractService<Shopsystem1ContractData>, Shopsystem1contractservice>();
    ioc.Register<IContractService<Shopsystem2ContractData>, Shopsystem2contractservice>();
    ioc.Register<IContractServic<Shopsystem3ContractData>, Shopsystem2contractservice>(); 

Но как я могу реализовать это в моем ContractController?

private readonly IContractService<ContractData> contract;


        public KontaktController(
            IContractService<ContractData> contract,
        {
            this.contract = contract;
        }

IContractService нужен тип, откуда он знает Shopsystem{1-3} ContractData?

Самый простой способ - создать Contractcontroller в Lib2 и Lib3, но было бы здорово, если бы я мог сделать это в моем globallib (lib1).У меня есть контроллеры в Lib 2 и Lib3, но только для явных конечных точек

Ответы [ 2 ]

1 голос
/ 19 июня 2019

Это похоже на случай для дженериков.
Вы должны сделать IContractservice дженерик.Вот так:

interface IContractservice<TContract> where TContract : ContractData
{
     List<TContract> GetContracts();
}

* * * * * * * * * * * * * * * * * * * * * * * * * * * where * * * * * * * * * * 10 * * * * * * * * * * * * * * * * * * * * * * * *

* * * * Затем вы должны реализовать его следующим образом:*

class Shopsystem1contractservice : IContractservice<Shopsystem1contractData>
{
     public List<Shopsystem1contractData> GetContracts()
     {

     }
}

Давайте поговорим о вашем редактировании:

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

  1. Поместите более явный тип для инъекции, например, используйте IContractservice<Shopsystem1contractData> внутри вашего контроллера.
  2. Зарегистрируйте определенный тип для IContract<ContractData> вместо более явного.

Оба из них, вероятно, ломают вашу систему, так почему вы делаете это так?Вам всегда нужно будет выбрать один из трех вариантов, и вы можете (как указано в пункте 2) зарегистрировать тот, который будет использоваться, если вас попросят выбрать общий вариант.

Я думаю, что это имеет смысл:

ioc.Register<IContract<ContractData>, Shopsystem2contractservice>(); 

Другие три вещи, которые вы зарегистрировали, являются избыточными, поскольку в настоящее время у вас есть только одна реализация IContract<Shopsystem1ContractData> и т. Д. Выоднако у вас есть несколько реализаций IContract<ContractData>, так что это то, что вы должны зарегистрировать.

Вы также должны иметь возможность зарегистрироваться ContractData, поэтому каждый раз, когда вы запрашиваете ContractData, он будет принимать ту, которую вы определили (например,. Shopsystem1contractData).

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

1 голос
/ 19 июня 2019

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

public interface IContractService<TData> where TData : ContractData
{
    List<TData> GetContracts();
}

public Shopsystem1ContractService : IContractService<Shopsystem1ContractData>
{   
    List<Shopsystem1ContractData> GetContracts(){...}
}

public Shopsystem2ContractService : IContractService<Shopsystem2ContractData>
{
    List<Shopsystem2ContractData> GetContracts(){...}    
}

public Shopsystem3contractservice : IContractservice<Shopsystem3ContractData>
{
    List<Shopsystem3ContractData> GetContracts(){...}    
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...