ant*_*eev 3 c# autofac .net-core
我有一个 net.core 3.1 托管服务应用程序。在此应用程序中,除了标准容器之外,autofac 还用作 DI 容器。我尝试添加并使用 IMemoryCache,如下所示:
\nHost.CreateDefaultBuilder(args)\n .ConfigureAppConfiguration(...)\n ...etc\n .UseServiceProviderFactory(new AutofacServiceProviderFactory())\n .ConfigureServices((hostContext, services) =>\n {\n // Register configuration\n services.AddMemoryCache();\n // some another services\n }\n .ConfigureContainer<ContainerBuilder>(ConfigureContainer)\n .UseConsoleLifetime();\nRun Code Online (Sandbox Code Playgroud)\n public class MyService: IMyService\n {\n private readonly IMemoryCache _memoryCache;\n \n public MyService(IMemoryCache memoryCache)\n {\n _memoryCache = memoryCache;\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n但是当应用程序启动时我得到这个异常:
\nAutofac.Core.DependencyResolutionException: An exception was thrown while activating \xce\xbb:Microsoft.Extensions.Hosting.IHostedService[] -> MyNamespace.WorkerService -> MyNamespace.MyAnotherService -> MyNamespace.SomeAnotherService -> MyNamespace.MyService -> Microsoft.Extensions.Caching.Memory.MemoryCache.\n ---> 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\'.\n ---> 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.\n at Microsoft.Extensions.Caching.Memory.MemoryCache..ctor(IOptions`1 optionsAccessor)\n at lambda_method(Closure , Object[] )\n at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()\n --- End of inner exception stack trace ---\n at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()\n at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)\n at Autofac.Core.Resolving.InstanceLookup.CreateInstance(IEnumerable`1 parameters)\n --- End of inner exception stack trace ---\n at Autofac.Core.Resolving.InstanceLookup.CreateInstance(IEnumerable`1 parameters)\n at Autofac.Core.Resolving.InstanceLookup.Execute()\n at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)\n at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(ResolveRequest request)\n at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)\n at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)\n at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)\n at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)\n at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable`1 parameters)\n at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)\n at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetService(Type serviceType)\n at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)\n at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)\n at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)\n at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)\n at MyNamespace.Program.Main(String[] args)\nRun Code Online (Sandbox Code Playgroud)\n我尝试在ConfigureContainer中使用autofac手动注册缓存服务所需的所有内容,而不是使用.AddMemoryCache()如下内容(从.AddMemoryCache()正文复制粘贴):
builder.RegisterType(typeof(OptionsManager<>)).As(typeof(IOptions<>)).SingleInstance();\nbuilder.RegisterType(typeof(OptionsManager<>)).As(typeof(IOptionsSnapshot<>));\nbuilder.RegisterType(typeof(OptionsMonitor<>)).As(typeof(IOptionsMonitor<>)).SingleInstance();\nbuilder.RegisterType(typeof(OptionsMonitor<>)).As(typeof(IOptionsFactory<>)).SingleInstance();\nbuilder.RegisterType(typeof(OptionsFactory<>)).As(typeof(IOptionsMonitorCache<>)).SingleInstance();\nbuilder.RegisterType<MemoryCache>().As<IMemoryCache>().SingleInstance();\nRun Code Online (Sandbox Code Playgroud)\n但在这种情况下我得到另一个例外:
\nSystem.ArgumentException: The type \'Microsoft.Extensions.Options.OptionsManager`1[TOptions]\' is not assignable to service \'Microsoft.Extensions.Options.IOptions`1\'.\n at Autofac.Builder.RegistrationBuilder.CreateRegistration(Guid id, RegistrationData data, IInstanceActivator activator, Service[] services, IComponentRegistration target, Boolean isAdapterForIndividualComponent)\n at Autofac.Builder.RegistrationBuilder.CreateRegistration[TLimit,TActivatorData,TSingleRegistrationStyle](IRegistrationBuilder`3 builder)\n at Autofac.Builder.RegistrationBuilder.RegisterSingleComponent[TLimit,TActivatorData,TSingleRegistrationStyle](IComponentRegistryBuilder cr, IRegistrationBuilder`3 builder)\n at Autofac.RegistrationExtensions.<>c__DisplayClass3_0.<RegisterType>b__0(IComponentRegistryBuilder cr)\n at Autofac.ContainerBuilder.Build(IComponentRegistryBuilder componentRegistry, Boolean excludeDefaultModules)\n at Autofac.ContainerBuilder.Build(ContainerBuildOptions options)\n at Autofac.Extensions.DependencyInjection.AutofacServiceProviderFactory.CreateServiceProvider(ContainerBuilder containerBuilder)\n at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)\n at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()\n at Microsoft.Extensions.Hosting.HostBuilder.Build()\nRun Code Online (Sandbox Code Playgroud)\n有什么建议么?
\n我发现了我的错误。多亏了 Sergey,我检查了我的 Program.cs,发现我.AddMemoryCache()曾经在ConfigureContainer 中注册 IMemoryCache 时使用过扩展。只需要使用扩展方法,无需手动注册IMemoryCache。