Как внедрить все классы, реализующие один и тот же интерфейс generi c в конструктор, используя StructureMap? - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть куча сборщиков данных, у всех почти одинаковая подпись. Единственное, что отличается, это тип возвращаемого значения. Тип возврата указан как T:

У меня есть этот интерфейс:

public interface IDataFetcher<T>
{
    T FetchData(MyObject data);
}

Далее у меня есть около 10 реализаций этого интерфейса. В коде вызова я хочу сделать что-то вроде этого:

public class FetchCommandHandler
{
    private readonly IEnumerable<IDataFetcher<T>> _fetchers;

    public FetchCommandHandler(IEnumerable<IDataFetcher<T>> fetchers) // this of course does not work
    {
        _fetchers = fetchers;
    }

    public MyResult Handle()
    {
        var myObj = new MyObject(); // get object from database

        foreach(var fetcher in _fetchers)
        {
           var result = fetcher.FetchData(myObj);
           // do something with result
        }
    }
}

Итак, в конце концов, мне не нужно вставлять каждую реализацию DataFetcher<T> в конструктор. Я ищу способ получить все регистрации IDataFetcher<T> из StructureMap.

Я открыт для любого другого проекта, который достигает того же результата, ie, а не для внедрения каждой реализации в конструктор.

1 Ответ

1 голос
/ 23 апреля 2020

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

Определить интерфейс:

public interface IData
{
}

public interface IDataFetcher<T> where T : IData
{
    T FetchData(MyObject data);
}

В качестве примера типа это будет возвращено:

public class FooData : IData
{
}

и его реализация DataFetcher будет выглядеть следующим образом:

public class FooDataFetcher : IDataFetcher<FooData>
{
     public FooData FetchData(MyObject data)
     {
       // logic here and return instance of FooData
     }
}

Теперь мы можем определить класс Handler примерно так:

public class FetchCommandHandler
{
    private readonly IEnumerable<IDataFetcher<IData>> _fetchers;

    public FetchCommandHandler(IEnumerable<IDataFetcher<IData>> fetchers) // this of course does not work
    {
        _fetchers = fetchers;
    }

    public MyResult Handle()
    {
        var myObj = new MyObject(); // get object from database

        foreach(var fetcher in _fetchers)
        {
           var result = fetcher.FetchData(myObj);
           // do something with result
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...