Я столкнулся с ошибкой выполнения при использовании autofac в сочетании с гибридным кешем и Redis. Я надеюсь, что кто-нибудь сможет объяснить, почему возникает эта ошибка.
При использовании autofac для разрешения экземпляра HybridCache в сочетании с redis autofac выдает исключение DependencyResolutionException, которое DefaultHybridCache пытается создать другой экземпляр самого себя. Это происходит при попытке разрешить экземпляр HybridcCache.
Полная ошибка:
DependencyResolutionException: конструктор типа «Microsoft.Extensions.Caching.Hybrid.Internal.DefaultHybridCache» попытался создать другой экземпляр самого себя. Это не разрешено, поскольку служба настроена на разрешение только одного экземпляра за весь срок действия.
Это происходит, когда я регистрирую Redis с общим мультиплексором. Я не уверен, почему это важно, код воспроизведения см. ниже. При использовании системы DI по умолчанию в .NET ошибок нет.
Итак, короткий вопрос: является ли это ошибкой в autofac (или библиотеке redis/hybridcache) или я неправильно использую библиотеки?
Минимальное воспроизведение выглядит следующим образом:
Добавление autofac в серверное приложение blazor, настроенное, как показано ниже, дает исключение при разрешении ГирбидКэш.
using Autofac.Extensions.DependencyInjection;
using BlazorAppAutofac.Components;
using BlazorAppAutofac.Services;
using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddHybridCache();
IConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect(new ConfigurationOptions
{
EndPoints = { $"localhost:6379" },
AbortOnConnectFail = false,
});
builder.Services.AddSingleton(connectionMultiplexer);
builder.Services.AddStackExchangeRedisCache(options =>
{
options.ConnectionMultiplexerFactory = () => Task.FromResult(connectionMultiplexer);
options.InstanceName = "BlazorAppAutofac";
});
builder.Services.AddTransient();
При использовании приведенного ниже кода для регистрации Redis (без добавления мультиплексора) исключение не возникает.
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("localhost:6379");
options.InstanceName = "BlazorAppAutofac";
});
В Home.razor
@inject IMessageService MessageService
В MessageService.cs
public class MessageService : IMessageService
{
private readonly HybridCache _cache;
public MessageService(HybridCache cache)
{
_cache = cache;
}
}
Я ожидал, что оба варианта регистрации будут работать, поскольку они также работают с внедрением зависимостей по умолчанию.
Интересно, что в коде StackExchangeRedis есть некоторый код, который пытается обойти эту проблему.
internal sealed class RedisCacheImpl : RedisCache
{
private readonly IServiceProvider _services;
internal override bool IsHybridCacheActive()
=> _services.GetService() is not null;
public RedisCacheImpl(IOptions optionsAccessor, ILogger logger, IServiceProvider services)
: base(optionsAccessor, logger)
{
_services = services; // important: do not check for HybridCache here due to dependency - creates a cycle
}
public RedisCacheImpl(IOptions optionsAccessor, IServiceProvider services)
: base(optionsAccessor)
{
_services = services; // important: do not check for HybridCache here due to dependency - creates a cycle
}
}
Трассировка стека:
DependencyResolutionException: The constructor of type 'Microsoft.Extensions.Caching.Hybrid.Internal.DefaultHybridCache' attempted to create another instance of itself. This is not permitted because the service is configured to only allowed a single instance per lifetime scope.
Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid id, Func creator)
Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid primaryId, Nullable qualifyingId, Func creator)
Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext context)
Autofac.Core.Resolving.ResolveOperation.InvokePipeline(ref ResolveRequest request, DefaultResolveRequestContext requestContext)
Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ref ResolveRequest request)
Autofac.Core.Resolving.ResolveOperation.Autofac.Core.Resolving.IResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ref ResolveRequest request)
Autofac.Core.Resolving.Pipeline.DefaultResolveRequestContext.ResolveComponent(ref ResolveRequest request)
Autofac.Core.Activators.Reflection.AutowiringParameter+c__DisplayClass0_0.b__0()
Autofac.Core.Activators.Reflection.BoundConstructor.Instantiate()
Autofac.Core.Activators.Reflection.ReflectionActivator+c__DisplayClass14_0.b__0(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Extensions.DependencyInjection.KeyedServiceMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action next)
Подробнее здесь: https://stackoverflow.com/questions/797 ... with-redis
Исключение AutoFac DependencyResolutionException при использовании гибридного кеша с Redis ⇐ C#
Место общения программистов C#
1760391052
Anonymous
Я столкнулся с ошибкой выполнения при использовании autofac в сочетании с гибридным кешем и Redis. Я надеюсь, что кто-нибудь сможет объяснить, почему возникает эта ошибка.
При использовании autofac для разрешения экземпляра HybridCache в сочетании с redis autofac выдает исключение DependencyResolutionException, которое DefaultHybridCache пытается создать другой экземпляр самого себя. Это происходит при попытке разрешить экземпляр HybridcCache.
Полная ошибка:
DependencyResolutionException: конструктор типа «Microsoft.Extensions.Caching.Hybrid.Internal.DefaultHybridCache» попытался создать другой экземпляр самого себя. Это не разрешено, поскольку служба настроена на разрешение только одного экземпляра за весь срок действия.
Это происходит, когда я регистрирую Redis с общим мультиплексором. Я не уверен, почему это важно, код воспроизведения см. ниже. При использовании системы DI по умолчанию в .NET ошибок нет.
Итак, короткий вопрос: является ли это ошибкой в autofac (или библиотеке redis/hybridcache) или я неправильно использую библиотеки?
Минимальное воспроизведение выглядит следующим образом:
Добавление autofac в серверное приложение blazor, настроенное, как показано ниже, дает исключение при разрешении ГирбидКэш.
using Autofac.Extensions.DependencyInjection;
using BlazorAppAutofac.Components;
using BlazorAppAutofac.Services;
using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddHybridCache();
IConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect(new ConfigurationOptions
{
EndPoints = { $"localhost:6379" },
AbortOnConnectFail = false,
});
builder.Services.AddSingleton(connectionMultiplexer);
builder.Services.AddStackExchangeRedisCache(options =>
{
options.ConnectionMultiplexerFactory = () => Task.FromResult(connectionMultiplexer);
options.InstanceName = "BlazorAppAutofac";
});
builder.Services.AddTransient();
При использовании приведенного ниже кода для регистрации Redis (без добавления мультиплексора) исключение не возникает.
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("localhost:6379");
options.InstanceName = "BlazorAppAutofac";
});
В Home.razor
@inject IMessageService MessageService
В MessageService.cs
public class MessageService : IMessageService
{
private readonly HybridCache _cache;
public MessageService(HybridCache cache)
{
_cache = cache;
}
}
Я ожидал, что оба варианта регистрации будут работать, поскольку они также работают с внедрением зависимостей по умолчанию.
Интересно, что в коде StackExchangeRedis есть некоторый код, который пытается обойти эту проблему.
internal sealed class RedisCacheImpl : RedisCache
{
private readonly IServiceProvider _services;
internal override bool IsHybridCacheActive()
=> _services.GetService() is not null;
public RedisCacheImpl(IOptions optionsAccessor, ILogger logger, IServiceProvider services)
: base(optionsAccessor, logger)
{
_services = services; // important: do not check for HybridCache here due to dependency - creates a cycle
}
public RedisCacheImpl(IOptions optionsAccessor, IServiceProvider services)
: base(optionsAccessor)
{
_services = services; // important: do not check for HybridCache here due to dependency - creates a cycle
}
}
Трассировка стека:
DependencyResolutionException: The constructor of type 'Microsoft.Extensions.Caching.Hybrid.Internal.DefaultHybridCache' attempted to create another instance of itself. This is not permitted because the service is configured to only allowed a single instance per lifetime scope.
Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid id, Func creator)
Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid primaryId, Nullable qualifyingId, Func creator)
Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext context)
Autofac.Core.Resolving.ResolveOperation.InvokePipeline(ref ResolveRequest request, DefaultResolveRequestContext requestContext)
Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ref ResolveRequest request)
Autofac.Core.Resolving.ResolveOperation.Autofac.Core.Resolving.IResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ref ResolveRequest request)
Autofac.Core.Resolving.Pipeline.DefaultResolveRequestContext.ResolveComponent(ref ResolveRequest request)
Autofac.Core.Activators.Reflection.AutowiringParameter+c__DisplayClass0_0.b__0()
Autofac.Core.Activators.Reflection.BoundConstructor.Instantiate()
Autofac.Core.Activators.Reflection.ReflectionActivator+c__DisplayClass14_0.b__0(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Extensions.DependencyInjection.KeyedServiceMiddleware.Execute(ResolveRequestContext context, Action next)
Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder+c__DisplayClass14_0.b__1(ResolveRequestContext context)
Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action next)
Подробнее здесь: [url]https://stackoverflow.com/questions/79789265/autofac-dependencyresolutionexception-when-using-hybrid-cache-with-redis[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия