Можем ли мы вызвать параметризованный конструктор из конструктора без параметров? - PullRequest
1 голос
/ 15 февраля 2020

Например, у меня есть такой класс

public class ABC
{
  private readonly IMemoryCache _cache;
  private readonly IConfiguration _config;
  private readonly IDistributedCache _distributedCache;

  public ABC(IMemoryCache memoryCache, IConfiguration config, IDistributedCache distributedCache)
  {
   _cache = memoryCache;
   _config = config;
   _distributedCache = distributedCache;
  }
  public ABC() : this(IMemoryCache , IConfiguration ,IDistributedCache )
  {
  }
}

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

Ответы [ 2 ]

2 голосов
/ 15 февраля 2020

Вам нужно передать конкретные реализации этих интерфейсов. Это похоже на вызов метода. Нет ничего магического в синтаксисе this(), кроме того, где он появляется. Например, если у вас есть реализация по умолчанию IMemoryCache, реализованная в классе DefaultMemoryCache, вы можете просто «обновить это» и передать ее:

public ABC() : this(new DefaultMemoryCache(), etc.)
{
}

В качестве альтернативы вы можете использовать stati c фабричный метод , если построение этих зависимостей слишком сложно:

public static ABC CreateNew()
{
    var others = ...
    var cache = new DefaultCache(others, etc.)
    ...
    return new ABC(cache, etc.);
} 

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

    public ABC() : this
    (
        (IMemoryCache) Activator.CreateInstance
        (
            Assembly.GetExecutingAssembly().GetTypes().First
            (
                t => typeof(IMemoryCache).IsAssignableFrom(t) && !t.IsInterface
            )
        )
    )
    {
    }

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

И последнее, просто для полного ответа, конечно, вы также можете внедрить тело в ваших перегруженных подрядчиках :

public class ABC
{
    private readonly ICache _cache;

    public ABC()
    {
        _cache = new Cache();
    }

    public ABC(ICache cache)
    {
        _cache = cache;
    }
}

: this() синтаксис требуется только в том случае, если Вы хотите вызвать другие конструкторы в том же классе FO Повторное использование кода.

1 голос
/ 15 февраля 2020

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

public class ABC
{
  private readonly IMemoryCache _cache;
  private readonly IConfiguration _config;
  private readonly IDistributedCache _distributedCache;

  public ABC(IMemoryCache memoryCache, IConfiguration config, IDistributedCache distributedCache)
  {
   _cache = memoryCache;
   _config = config;
   _distributedCache = distributedCache;
  }
  public ABC() : this(new MemoryCache(), new Configuration(), new DistributedCache() )
  {
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...