Я зарегистрировал реализацию своего регистратора в ServiceCollection при запуске:
services.AddTransient(typeof(ILogger<>), typeof(GenericLogger<>));
Обычно я делаю это для внедрения с помощью конструктора:
class DynamoEventProcessor
{
private readonly IRepository _repository;
private readonly IDogStatsd _dogStatsd;
private readonly ILogger<DynamoEventProcessor> _logger;
public DynamoEventProcessor(IRepository repository, IDogStatsd dogStatsd, ILogger<DynamoEventProcessor> logger)
{
_repository = repository;
_dogStatsd = dogStatsd;
_logger = logger;
}
}
Но у меня есть класс, в котором нет конструктора:
public class ProfileContent
{
public MemoryStream Content { get; set; }
public string ContentAlgorithm { get; set; }
public List<Dictionary<string, AttributeValue>> DataKeys { get; set; }
public long ExpiresUtc { get; set; }
public long Version { get; set; }
public long Deleted { get; set; }
public static Dictionary<string, EncryptedDataAndKeys> GetEncryptedDataAndKeys(Dictionary<string, Dictionary<string, AttributeValue>> profileContentAttributes)
{
_logger.LogInformation("Available Keys: " + KeysAsString(keyList));
_logger.LogInformation("AccountId missing Coporate Data: " + _converter.GetValueFromAttributeValue(attributes["AccountId"]).ToString());
var encryptedDataAndKeys = new Dictionary<string, EncryptedDataAndKeys>();
foreach (var item in profileContentAttributes)
{
encryptedDataAndKeys.Add(item.Key, GetEncryptedDataAndKey(item.Value));
}
return encryptedDataAndKeys;
}
}
Мой _logger потерпел неудачу здесь из-за нуля. Я понимаю проблему, что я не ввел его должным образом. Как я могу внедрить его, когда я использую его в статическом методе без создания экземпляра объекта?
Возможный дубликат Как использовать DI внутри статического метода в Asp.net Core rc1





Вы не можете внедрить в статический конструктор. У вас есть несколько вариантов:
1.) Передайте ILogger в метод, надеюсь, вызывающий код внедрил его.
2.) Иметь статическое свойство для ILogger в ProfileContent, а затем в вашем файле Startup в методе Configure инициализировать его, т.е.
ProfileContent.Logger = app.ApplicationServices.GetService<ILogger<ProfileContent>>();
затем используйте Logger в своем статическом методе. Лично я бы остановился на варианте 1.
Единственное, что я мог бы добавить к этому: 3) Избавьтесь от статики, с регистрацией Singleton в DI, действительно ли этот класс должен быть статичным?
Вы предпочли вариант 1. Вариант 2. Для меня было намного меньше кода. В чем причина предпочтения варианта 1?
Вариант 2 — анти-паттерн локатора сервисов. Он также блокирует создание и назначение Logger, и, как правило, я не сторонник статических свойств.
Я бы сделал статический метод сервисом (возможно, синглтоном) и зарегистрировал его в контейнере. Другим решением было бы передать необходимую услугу в качестве параметра. Если вы действительно хотите пойти тем же путем, что и сейчас, вам нужен сервисный локатор, то есть не рекомендуется.