Это включает в себя 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.