Внедрение зависимостей с помощью autofac C # — можно ли указать заводской метод при регистрации универсального типа

#c# #asp.net-core #dependency-injection #autofac #confluent-kafka-dotnet

#c# #asp.net-ядро #внедрение зависимостей #autofac #слияние-kafka-dotnet #asp.net-core #Внедрение зависимостей #confluent-kafka-dotnet

Вопрос:

Я очень новичок в DI и autofac. У меня есть одноэлементный класс ProducerService , как указано ниже. Это используется как зависимость в конструкторе BackgroundService. В ProducerService есть зависимость, введенная конструктором, IKafkaProducerAggregate , также перечисленная ниже.

Как я могу создать единственный экземпляр IKafkaProducerAggregate<TKey, Tvalue> , который создается для внедрения в ProducerService<TKey, TValue> ? Это содержит экземпляр IProducer из внешней библиотеки Kafka confluent dotnet с помощью заводского метода IProducer<TKey, TValue> producer = new ProducerBuilder<TKey, TValue>(Config.Producer).Build(); . Могу ли я использовать какой-то заводской метод с Autofac, который создает экземпляр aggregate и инициализирует IProducer с помощью фабричного метода Kafka confluences?

Пока у меня есть модуль Autofac, который регистрирует службу производителя, и я изо всех сил пытаюсь понять, как использовать что-то похожее на заводской метод??? это создало бы IKafkaProducerAggregate при создании ProducerService :

 Assembly serializers = typeof(ConsumerService).GetTypeInfo().Assembly;

builder.RegisterGeneric(typeof(ProducerService<,>))
    .As(typeof(IKafkaProducer<,>))
    .SingleInstance();
  

Интерфейс: IKafkaProducerAggregate

 public interface IKafkaProducerAggregate<TKey, TValue>
{
    IProducer<TKey, TValue> Producer { get; }
    Action<DeliveryReport<TKey, TValue>> DeliveryReportAction { get; }
}
  

Класс: ProducerService

 namespace WebApp.Kafka
{
    public class ProducerService<Key, Value> : IProducerService<Key, Value>, IDisposable
    {
        private bool Disposed { get; set; }
        private IKafkaProducerAggregate<Key, Value> ProducerAggregate { get; }
        private ILogger Logger { get; set; }


        ProducerService(
            IKafkaProducerAggregate<Key, Value> aggregate,
            ILogger<ProducerService<Key, Value>> logger)
        {
            Logger = logger ?? throw new ArgumentNullException(nameof(logger));
            ProducerAggregate = aggregate ?? throw new ArgumentNullException(nameof(aggregate));

            Disposed = false;

            Logger.LogInformation("ProducerService constructor called");
        }

        public void Produce(string topic, Key key, Value value)
        {
            ProducerAggregate.Producer.Produce(topic, new Message<Key, Value> { Key = key, Value = value }, ProducerAggregate.DeliveryReportAction);

            Logger.LogInformation("Produce topic : {}, key : {}, value : {}", topic, key.ToString(), value.ToString());
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!Disposed)
            {
                if (disposing)
                {
                    Logger.LogInformation("Disposing Kafka producer...");
                    ProducerAggregate.Producer.Dispose();
                }

                Disposed = true;
            }
        }

        ~ProducerService()
        {
            Dispose(false);
        }
    }
}
  

Комментарии:

1. Вам нужен один экземпляр для каждого общего экземпляра, правильно?

2. Да, в одном экземпляре ProducerService этого параметра параметр IKafkaProducerAggregate создан с использованием какого-то заводского метода, позволяющего создавать его IProducer свойство.

Ответ №1:

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

https://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html

Комментарии:

1. Привет, спасибо за ответ. Я добавил дополнительные подробности в свой вопрос. Сам ProducerService используется как зависимость в a BackgroundService . Следовательно, я хочу, чтобы был создан только один экземпляр ProducerService. IProducer Экземпляр в агрегате должен быть создан с помощью фабрики внешней библиотеки Kafka confluent из dotnet.

2. Немного сложно привести пример, я предлагаю вам взглянуть на документацию autofaccn.readthedocs.io/en/latest/register/registration.html . Взгляните на пример, представленный фразой «Вы также можете использовать делегаты для предоставления закрытого универсального типа …».