如何基于枚举参数获得正确的服务?

时间:2019-11-20 17:41:30

标签: c# .net .net-core

我有一个类似下面的实现。该代码仅用于说明问题,不是真正的实现。我有一个以上的数据存储库,我只想拥有一个数据服务,并且想在控制器中注入和使用该数据服务,但是我不喜欢在实现中使用这种切换用例。有没有更好的方法或设计呢?或有什么建议吗? 始终欢迎任何更好的设计。预先感谢。

interface IDataService<T>
{
    Task<T> Get(RepoTypes repoType);
}

class DataService<T>:IDataService<T>
{
    private readonly IRepository<X> _xRepository;
     private readonly IRepository<Y> _yRepository;
    private readonly  IRepository<Z> _zRepository;
    private readonly  IMapper _mapper;

    public ClassName(IRepository<X> xRepository,
    IRepository<Y> yRepository,
    IRepository<Z> zRepository,
    IMapper mapper)
    {
        _xRepository = xRepository;
        _yRepository = yRepository;
        _zRepository = zRepository;
        _mapper = mapper;
    }
    public async Task<T>  GetTask(RepoTypes repoType)
    {
        switch (repoTypes)
        {
            case X:
                var data = await _xRepository.Get();
                return _mapper.Map<T>(data);
            case Y:
                var data = await _yRepository.Get();
                return _mapper.Map<T>(data);
            case Y:
                var data = await _zRepository.Get();
                return _mapper.Map<T>(data);
            default:
        }
    }
}

interface IRepository<T>
{
    Task<T> Get();
}
class IRepository<T>: IRepository<T>
{
    public async Task<T>  GetTask()
    {
        // some implementation
    }
}

public enum RepoTypes
{
    X,
    Y,
    Z
}

1 个答案:

答案 0 :(得分:1)

很难给出没有具体说明的答案。另外,示例代码也不可编译和/或不正确。

我还对体系结构有很多疑问,却不知道很难提供正确或令人满意的答案。

至少让我尝试一下,以帮助您摆脱switch语句。一种可行的方法是简单地将值存储为键值对,并在Get(RepoTypes repoType)中检索这些值,例如,您可以按以下方式重新利用DataService类:

public class DataService<T> : IDataService<T>
{
  private readonly IMapper _mapper;

  private Dictionary<RepoTypes, dynamic> _dict;

  public DataService(IRepository<ClassX> xRepository,
                     IRepository<ClassY> yRepository,
                     IRepository<ClassZ> zRepository,
                     IMapper mapper)
  {
    _mapper = mapper;

    _dict = new Dictionary<RepoTypes, dynamic>
    {
      { RepoTypes.X, xRepository },
      { RepoTypes.Y, yRepository },
      { RepoTypes.Z, zRepository }
    };
  }

  public async Task<T> Get(RepoTypes repoType)
  {
    var repo = _dict[repoType];
    var data = await repo.Get();
    return _mapper.Map<T>(data);
  }
}

由于不同的IRepository接口之间的类型不同,除Dictionary<RepoTypes, dynamic>之外,没有其他方法可以指定字典。