antonalekseev
antonalekseev

Reputation: 109

Can't resolve IMemoryCache dependency

I have a net.core 3.1 hosted service application. In this app, autofac is used as a DI container in addition to a standard container. I try to adding and use IMemoryCache as following:

  1. In Program.cs
Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration(...)
    ...etc
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .ConfigureServices((hostContext, services) =>
    {
        // Register configuration
        services.AddMemoryCache();
        // some another services
    }
    .ConfigureContainer<ContainerBuilder>(ConfigureContainer)
    .UseConsoleLifetime();
  1. ConfigureContainer is a method where some types are registered using autofac.
  2. In my service I add memory cache dependency as following:
    public class MyService: IMyService
    {
        private readonly IMemoryCache _memoryCache;
        
        public MyService(IMemoryCache memoryCache)
        {
            _memoryCache = memoryCache;
        }
    }

But I get this exception when application was started:

Autofac.Core.DependencyResolutionException: An exception was thrown while activating λ:Microsoft.Extensions.Hosting.IHostedService[] -> MyNamespace.WorkerService -> MyNamespace.MyAnotherService -> MyNamespace.SomeAnotherService -> MyNamespace.MyService -> Microsoft.Extensions.Caching.Memory.MemoryCache.
 ---> Autofac.Core.DependencyResolutionException: An exception was thrown while invoking the constructor 'Void .ctor(Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Caching.Memory.MemoryCacheOptions])' on type 'MemoryCache'.
 ---> System.TypeLoadException: Method 'get_Size' in type 'Microsoft.Extensions.Caching.Memory.CacheEntry' from assembly 'Microsoft.Extensions.Caching.Memory, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' does not have an implementation.
   at Microsoft.Extensions.Caching.Memory.MemoryCache..ctor(IOptions`1 optionsAccessor)
   at lambda_method(Closure , Object[] )
   at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()
   --- End of inner exception stack trace ---
   at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()
   at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.CreateInstance(IEnumerable`1 parameters)
   --- End of inner exception stack trace ---
   at Autofac.Core.Resolving.InstanceLookup.CreateInstance(IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
   at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(ResolveRequest request)
   at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
   at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)
   at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
   at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)
   at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at MyNamespace.Program.Main(String[] args)

I tried register all needed for caching services manually using autofac in ConfigureContainer instead of using .AddMemoryCache() as following (copy paste from .AddMemoryCache() body):

builder.RegisterType(typeof(OptionsManager<>)).As(typeof(IOptions<>)).SingleInstance();
builder.RegisterType(typeof(OptionsManager<>)).As(typeof(IOptionsSnapshot<>));
builder.RegisterType(typeof(OptionsMonitor<>)).As(typeof(IOptionsMonitor<>)).SingleInstance();
builder.RegisterType(typeof(OptionsMonitor<>)).As(typeof(IOptionsFactory<>)).SingleInstance();
builder.RegisterType(typeof(OptionsFactory<>)).As(typeof(IOptionsMonitorCache<>)).SingleInstance();
builder.RegisterType<MemoryCache>().As<IMemoryCache>().SingleInstance();

but in this case I get another exception:

System.ArgumentException: The type 'Microsoft.Extensions.Options.OptionsManager`1[TOptions]' is not assignable to service 'Microsoft.Extensions.Options.IOptions`1'.
   at Autofac.Builder.RegistrationBuilder.CreateRegistration(Guid id, RegistrationData data, IInstanceActivator activator, Service[] services, IComponentRegistration target, Boolean isAdapterForIndividualComponent)
   at Autofac.Builder.RegistrationBuilder.CreateRegistration[TLimit,TActivatorData,TSingleRegistrationStyle](IRegistrationBuilder`3 builder)
   at Autofac.Builder.RegistrationBuilder.RegisterSingleComponent[TLimit,TActivatorData,TSingleRegistrationStyle](IComponentRegistryBuilder cr, IRegistrationBuilder`3 builder)
   at Autofac.RegistrationExtensions.<>c__DisplayClass3_0.<RegisterType>b__0(IComponentRegistryBuilder cr)
   at Autofac.ContainerBuilder.Build(IComponentRegistryBuilder componentRegistry, Boolean excludeDefaultModules)
   at Autofac.ContainerBuilder.Build(ContainerBuildOptions options)
   at Autofac.Extensions.DependencyInjection.AutofacServiceProviderFactory.CreateServiceProvider(ContainerBuilder containerBuilder)
   at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()

Any suggestions?

Upvotes: 4

Views: 6360

Answers (1)

antonalekseev
antonalekseev

Reputation: 109

I found my mistake. Thanks to Sergey, I check my Program.cs and discovered that I use .AddMemoryCache() extension at one time with register IMemoryCache in ConfigureContainer. Only the extension method needs to be used, no manual registration of IMemoryCache needed.

Upvotes: 6

Related Questions