Разрешение на родительский интерфейс во время внедрения конструктора - PullRequest
0 голосов
/ 14 июня 2019

Это включает в себя autofac и c #.У меня есть интерфейс, производный от родительского интерфейса:

public interface IJ4JLogger<out TCalling>
{
}

public interface IJ4JSmsLogger<out TCalling> : IJ4JLogger<TCalling>
{
}

Некоторые классы зависят от того, предоставляется ли экземпляр родительского интерфейса во время создания:

public FileHistoryConfiguration( IJ4JLogger<FileHistoryConfiguration> histLogger, IJ4JLogger<FileHistoryService> svcLogger )
{
}

Но если я регистрирую тип какэто с autofac:

builder.RegisterGeneric( typeof(J4JSmsLogger<>) )
    .As(typeof(IJ4JSmsLogger<>))
    .SingleInstance();

, где J4JSmsLogger <> является классом, реализующим IJ4JSmsLogger <>, тогда этот вызов завершается ошибкой, что он не может найти ничего зарегистрированного для предоставления интерфейса IJ4JLogger <>:

_fhConfig = _svcProvider.GetRequiredService<IFileHistoryConfiguration>();

Я могу обойти эту проблему, изменив предложение As <> в регистрации J4JSmsLogger <>, чтобы оно рассматривалось как экземпляр IJ4JLogger <>, а затем приведу результат разрешения этого интерфейса к IJ4JSmsLogger <>всякий раз, когда мне нужны дополнительные возможности дочернего интерфейса.

Но я не понимаю, почему я должен это делать.Есть ли дополнительный шаг, который мне нужно предпринять во время регистрации типов с помощью autofac, чтобы объекты, реализующие дочерний интерфейс, удовлетворяли потребность в родительском интерфейсе?

Обходной путь очистки

Читая больше об autofac, я узнал кое-что новое: вы можете определить столько предложений As <> () (включая AsSelf ()), сколько захотите.Поэтому изменение моей конфигурации автозапуска на:

builder.RegisterGeneric( typeof(J4JSmsLogger<>) )
    .As(typeof(IJ4JSmsLogger<>))
    .As(typeof(IJ4JLogger<>))
    .SingleInstance();

обеспечивает более чистое решение, чем постоянное приведение разрешенных экземпляров.

Я не собираюсь представлять его как ответ, потому что мне любопытнопочему autofac не выполняет такого рода downcasting автоматически, и делают ли какие-либо другие структуры DI.

1 Ответ

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

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

public class BadTimes
{
  public BadTimes(object input) { }
}

Какой объект он туда поместил? Все сводится к объекту.

Однако вы всегда можете зарегистрировать его как оба типа и назвать его днем:

builder.RegisterGeneric(typeof(J4JSmsLogger<>))
    .As(typeof(IJ4JSmsLogger<>))
    .As(typeof(IJ4JLogger<>))
    .SingleInstance();
...