Can't resolve IMemoryCache dependency - c#

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:
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();
ConfigureContainer is a method where some types are registered using autofac.
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?

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.

Related

ASP.NET Core 3: Cannot resolve scoped service 'Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]' from root provider

When I run the project, I encounter this problem:
(I've used asp.net core 3.)
Cannot resolve scoped service 'Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]' from root provider.
How can I solve this problem?
ApplicationDbContext class:
public class ApplicationDbContext : IdentityDbContext<User, Role, int,
UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public static async Task CreateAdminAccount(IServiceProvider
serviceProvider, IConfiguration configuration)
{
UserManager<User> userManager =
serviceProvider.GetRequiredService<UserManager<User>>();
RoleManager<Role> roleManager =
serviceProvider.GetRequiredService<RoleManager<Role>>();
string userName = configuration["Data:AdminUser:Name"];
string email = configuration["Data:AdminUser:Email"];
string password = configuration["Data:AdminUser:Password"];
string role = configuration["Data:AdminUser:Role"];
if (await userManager.FindByNameAsync(userName) == null)
{
if (await roleManager.FindByNameAsync(role) == null)
{
await roleManager.CreateAsync(new Role(role));
}
User user = new User
{
Email = email,
UserName = userName
};
var result = userManager.CreateAsync(user, password);
if (result.IsCompletedSuccessfully)
{
await userManager.AddToRoleAsync(user, role);
}
}
}
}
Details of error:
An error occurred while starting the application. AggregateException:
One or more errors occurred. (Cannot resolve scoped service
'Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]'
from root provider.)
System.Threading.Tasks.Task.ThrowIfExceptional(bool
includeTaskCanceledExceptions)
InvalidOperationException: Cannot resolve scoped service
'Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]'
from root provider.
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type
serviceType, IServiceScope scope, IServiceScope rootScope)
AggregateException: One or more errors occurred. (Cannot resolve
scoped service
'Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]'
from root provider.)
System.Threading.Tasks.Task.ThrowIfExceptional(bool
includeTaskCanceledExceptions) System.Threading.Tasks.Task.Wait(int
millisecondsTimeout, CancellationToken cancellationToken)
System.Threading.Tasks.Task.Wait()
Alpha.Web.App.Startup.Configure(IApplicationBuilder app,
IWebHostEnvironment env) in Startup.cs
+
ApplicationDbContext.CreateAdminAccount(app.ApplicationServices,
Configuration).Wait(); System.RuntimeMethodHandle.InvokeMethod(object
target, object[] arguments, Signature sig, bool constructor, bool
wrapExceptions) System.Reflection.RuntimeMethodInfo.Invoke(object obj,
BindingFlags invokeAttr, Binder binder, object[] parameters,
CultureInfo culture)
Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(object instance,
IApplicationBuilder builder)
Microsoft.AspNetCore.Hosting.ConfigureBuilder+<>c__DisplayClass4_0.b__0(IApplicationBuilder
builder)
Microsoft.AspNetCore.Hosting.GenericWebHostBuilder+<>c__DisplayClass13_0.b__2(IApplicationBuilder
app)
Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter+<>c__DisplayClass0_0.g__MiddlewareFilterBuilder|0(IApplicationBuilder
builder)
Microsoft.AspNetCore.Server.IIS.Core.IISServerSetupFilter+<>c__DisplayClass2_0.b__0(IApplicationBuilder
app)
Microsoft.AspNetCore.HostFilteringStartupFilter+<>c__DisplayClass0_0.b__0(IApplicationBuilder
app)
Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken
cancellationToken)
Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken
cancellationToken)
Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost
host, CancellationToken token)
Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost
host, CancellationToken token)
Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost
host) Alpha.Web.App.Program.Main(string[] args) in Program.cs
+
CreateHostBuilder(args).Build().Run();
Show raw exception details InvalidOperationException: Cannot resolve
scoped service
'Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]'
from root provider.
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type
serviceType, IServiceScope scope, IServiceScope rootScope)
Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(Type
serviceType, IServiceScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type
serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type
serviceType)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider
provider, Type serviceType)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider
provider)
Alpha.DataAccess.ApplicationDbContext.CreateAdminAccount(IServiceProvider
serviceProvider, IConfiguration configuration) in
ApplicationDbContext.cs
+
UserManager userManager = serviceProvider.GetRequiredService>();
Show raw exception details System.InvalidOperationException: Cannot
resolve scoped service
'Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]'
from root provider. at
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type
serviceType, IServiceScope scope, IServiceScope rootScope) at
Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(Type
serviceType, IServiceScope scope) at
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type
serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type
serviceType) at
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider
provider, Type serviceType) at
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider
provider) at
Alpha.DataAccess.ApplicationDbContext.CreateAdminAccount(IServiceProvider
serviceProvider, IConfiguration configuration) in
E:\Archives\Projects\Alpha\Alpha.DataAccess\ApplicationDbContext.cs:line
92 .NET Core 3.0.0 X64 v4.0.0.0 | Microsoft.AspNetCore.Hosting
version 3.0.0-rc2.19465.2 | Microsoft Windows 10.0.17763 |
Need help?
From the screenshot you've included, it shows that you've got the following line in Startup.Configure:
ApplicationDbContext.CreateAdminAccount(app.ApplicationServices, Configuration)
.Wait();
The IServiceProvider instance stored in IApplicationBuilder.ApplicationServices is the root service provider for your application. The error message states that it cannot resolve a scoped service from the root service provider.
This issue comes up often, but the easiest solution for your scenario is to inject IServiceProvider into your Configure method and pass that into CreateAdminAccount:
public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider)
{
ApplicationDbContext.CreateAdminAccount(serviceProvider, Configuration)
.Wait();
}
The instance of IServiceProvider that gets passed into Configure is scoped, which means that you can use it to create scoped services.
That's all you need to make this work, but it's more typical to do this type of seeding in Program. That keeps seeding concerns separate from configuring the pipeline and it also allows the use of async/await. Here's an example:
public class Program
{
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var serviceProvider = scope.ServiceProvider;
var config = serviceProvider.GetRequiredService<IConfiguration>();
await ApplicationDbContext.CreateAdminAccount(serviceProvider, config);
}
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
// ...
}
You could resolve UserManager<User> and RoleManager<Role> in Main too, and pass those in to CreateAdminAccount rather than having it use the service-locator approach.

How to make autofac KeyFilter works in asp.net-core web api?

Cannot use KeyFilter attribute to resolve registered type in asp.net core web api 2.2
I wanna use Autofac to resolve different instance of a type. I registered type in Startup.ConfigureServices by using RegisterType().Keyed and RegisterType().Named.
I can use IContainer.ResolveKeyed to resolve instance, but can't use KeyFilter to resolve instance in constructor
Startup
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public static IContainer Container { get; private set; }
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddControllersAsServices();
var builder = new ContainerBuilder();
builder.Populate(services);
builder.RegisterType<Foobar>().UsingConstructor(typeof(string)).WithParameter("name", "Eric").Named<Foobar>("Eric").SingleInstance();
builder.RegisterType<Foobar>().UsingConstructor(typeof(string)).WithParameter("name", "Fred").Keyed<Foobar>("Fred").SingleInstance();
Container = builder.Build();
var serviceProvider = new AutofacServiceProvider(Container);
return serviceProvider;
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
ValuesController
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly Foobar fb1;
private readonly Foobar fb2;
public ValuesController([KeyFilter("Eric")]Foobar fbEric, [KeyFilter("Fred")]Foobar fbFred)
{
// KeyFilter not work
fb1 = fbEric;
fb2 = fbFred;
// Container.ResolvedKeyed work
fb1 = Startup.Container.ResolveKeyed<Foobar>("Eric");
fb2 = Startup.Container.ResolveNamed<Foobar>("Fred");
}
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { fb1.Say(), fb2.Say() };
}
}
Use KeyFilter will throw below exceptions:
An unhandled exception has occurred while executing the request.
Autofac.Core.DependencyResolutionException: An exception was thrown while activating Autofac.MI.WebApi.Controllers.ValuesController. ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Autofac.MI.WebApi.Controllers.ValuesController' can be invoked with the available services and parameters:
Cannot resolve parameter 'Autofac.MI.ClassLib.Foobar fbEric' of constructor 'Void .ctor(Autofac.MI.ClassLib.Foobar, Autofac.MI.ClassLib.Foobar)'.
at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext context, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\Core\Activators\Reflection\ReflectionActivator.cs:line 160
at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\Core\Activators\Reflection\ReflectionActivator.cs:line 120
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget) in C:\projects\autofac\src\Autofac\Core\Resolving\InstanceLookup.cs:line 117
--- End of inner exception stack trace ---
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget) in C:\projects\autofac\src\Autofac\Core\Resolving\InstanceLookup.cs:line 135
at Autofac.Core.Resolving.InstanceLookup.Execute() in C:\projects\autofac\src\Autofac\Core\Resolving\InstanceLookup.cs:line 83
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\Core\Resolving\ResolveOperation.cs:line 131
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\Core\Resolving\ResolveOperation.cs:line 84
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) in C:\projects\autofac\src\Autofac\ResolutionExtensions.cs:line 1041
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters) in C:\projects\autofac\src\Autofac\ResolutionExtensions.cs:line 871
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.AspNetCore.Mvc.Controllers.ServiceBasedControllerActivator.Create(ControllerContext actionContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
For KeyFilter, you need to register the service with WithAttributeFiltering.
For AddControllersAsServices, it only register the service to service collection, but it did not register with WithAttributeFiltering.
Try code below:
services.AddMvc().AddControllersAsServices().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
var builder = new ContainerBuilder();
builder.Populate(services);
builder.RegisterType<Foobar>().UsingConstructor(typeof(string)).WithParameter("name", "Eric").Named<Foobar>("Eric").SingleInstance();
builder.RegisterType<Foobar>().UsingConstructor(typeof(string)).WithParameter("name", "Fred").Keyed<Foobar>("Fred").SingleInstance();
var controllers = typeof(Startup).Assembly.GetTypes().Where(t => t.BaseType == typeof(ControllerBase)).ToArray(); // for api controller
//var controllers = typeof(Startup).Assembly.GetTypes().Where(t => t.BaseType == typeof(Controller)).ToArray(); // for mvc controller
builder.RegisterTypes(controllers).WithAttributeFiltering();
Container = builder.Build();

Cannot resolve Azure Service Fabric service with AutoFac even all objects are available

I am trying to inject using Autofac:
Unhealthy event: SourceId='System.RA', Property='ReplicaOpenStatus', HealthState='Warning', ConsiderWarningAsError=false.
Replica had multiple failures during open on _Node_0. API call: IStatelessServiceInstance.Open(); Error = Autofac.Core.DependencyResolutionException (-2146233088)
An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = ServiceFabricProxy (DelegateActivator), Services = [MYSERVICE.ServiceFabric.ServiceFabric], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = ExternallyOwned ---> An error occurred during the activation of a particular registration. See the inner exception for
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
at Autofac.Core.Resolving.InstanceLookup.Execute()
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters)
at Autofac.Integration.ServiceFabric.StatelessServiceFactoryRegistration.<>c__DisplayClass0_0`1.b__0(StatelessServiceContext context)
at Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceFactory.System.Fabric.IStatelessServiceFactory.CreateInstance(String serviceTypeName, Uri serviceName, Byte[] initializationData, Guid partitionId, Int64 instanceId)
at System.Fabric.ServiceFactoryBroker.<>c__DisplayClass9_0.b__0(IStatelessServiceFactory factory, ServiceInitializationParameters initParams)
at System.Fabric.ServiceFactoryBroker.CreateHelper[TFactory,TReturnValue](IntPtr nativeServiceType, IntPtr nativeServiceName, UInt32 initializationDataLength, IntPtr nativeInitializationData, Guid partitionId, Func`3 creationFunc, Action`2 initializationFunc, ServiceInitializationParameters initializationParameters)
For more information see: http://aka.ms/sfhealth
These errors are always frustrating as they don't stop Visual Studio!
public ServiceFabric(StatelessServiceContext context, ServiceLoggerFactory serviceLoggerFactory, ServiceConfiguration configuration)
: base(context)
{
Argument.IsNotNull(() => context);
Argument.IsNotNull(() => serviceLoggerFactory);
Argument.IsNotNull(() => configuration);
_log = serviceLoggerFactory.EnrichLoggerForStatelessServiceContext(this);
_log.Information($"Service constructed {GetType().FullName}");
}
I have verified that the classes in my constructor have been registered:
public class NodeAutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var assembly = typeof(GlobalAutofacModule).Assembly;
var appName = assembly.GetName().Name;
var appVersion = assembly.InformationalVersion();
builder.Register<ILogger>(container => LoggingHelper.ConfigureLogging(appName, appVersion))
.SingleInstance();
builder.RegisterType<ServiceLoggerFactory>()
.SingleInstance();
builder.RegisterType<ServiceConfiguration>()
.AsSelf()
.SingleInstance();
// TODO: Register services here
}
}
I find AutoFac really frustrating to work with when it can't resolve a constructor.
Are there any ways to get more information when this happens?
I am creating my container when my Service Fabric service starts up.
Paul
Cut stacktrace in SF errors is really annoying. But there is a way to get more details of the error. Try the following after configuration of your container:
using (var c = builder.Build())
{
var s = c.Resolve<ServiceFabric>();
}
Thus you'll get access to the full Exception information and will be able to specify the problem.

HangFire doesn't like it when I register a Func in DI

I have a class which requires a Func to be injected into its constructor. The class is called SomeClassThatNeedsFunc:
// register a factory function to create a db context to be used in singleton classes
services.AddTransient<Func<MyCustomContext>>(provider => (() =>
{
var dbContextOptionsBuilder = new DbContextOptionsBuilder<MyCustomContext>();
dbContextOptionsBuilder.UseSqlServer(sqlConnectionString);
return new MyCustomContext(dbContextOptionsBuilder.Options);
}));
// register class that needs the factory:
services.AddSingleton<SomeClassThatNeedsFunc>();
I get exception:
warn: Hangfire.AutomaticRetryAttribute[0]
Failed to process the job '4': an exception occurred. Retry attempt 3 of 10 will be performed in 00:01:55.
System.InvalidOperationException: Unable to resolve service for type 'System.Func`1[System.Threading.Tasks.VoidTaskResult]' while attempting to activate 'System.Threading.Tasks.Task`1[System.Threading.Tasks.VoidTaskResult]'.
at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type)
at Hangfire.AspNetCore.AspNetCoreJobActivatorScope.Resolve(Type type)
at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.<PerformJobWithFilters>b__0()
at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_1.<PerformJobWithFilters>b__2()
at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)
at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)

Autofac cannot resolve parameter ApplicationUserManager

I'm trying to configure Autofac to play nice with my Web API/Oauth Identity project, but it does not seem to work. I keep getting the 'cannot resolve parameter ApplicationUserManager on constructor ....'
This is the service which doesn't get instantiated:
public class EmployeeService : Service<Employee>, IEmployeeService
{
private readonly ApplicationUserManager _userManager;
public EmployeeService(IUnitOfWork uow, ApplicationUserManager userManager)
: base(uow)
{
_userManager = userManager;
}
// .. other code
}
The ApplicationUserManager:
public class ApplicationUserManager : UserManager<Employee>
{
public ApplicationUserManager(IUserStore<Employee> store, IdentityFactoryOptions<ApplicationUserManager> options)
: base(store)
{
this.EmailService = new EmailService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
this.UserTokenProvider = new DataProtectorTokenProvider<Employee>(dataProtectionProvider.Create("ASP.NET Identity"))
{
//Code for email confirmation and reset password life time
TokenLifespan = TimeSpan.FromHours(6)
};
}
// UserValidator and PasswordValidator
// ...
}
}
And the autofac configuration:
public static void RegisterAutofac()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyTypes(typeof(IRepository<>).Assembly).AsClosedTypesOf(typeof(IRepository<>));
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces();
// Tried, doesn't work:
//builder.RegisterType<MyContext>();
//builder.RegisterType<UserStore<Employee>>().AsImplementedInterfaces();
//builder.RegisterType<ApplicationUserManager>().As<UserManager<Employee>>();
// Also doesn't work:
builder.RegisterInstance(new MyContext());
builder.RegisterType<UserStore<Employee>>().AsImplementedInterfaces().InstancePerRequest();
builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c =>
new IdentityFactoryOptions<ApplicationUserManager>()
{
DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ApplicationN‌​ame")
});
builder.RegisterType<ApplicationUserManager>().As<UserManager<Employee>>().InstancePerRequest();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
var resolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
The folllowing did work, but doesn't use DI:
public class EmployeeService : Service<Employee>, IEmployeeService
{
private readonly ApplicationUserManager _userManager;
public EmployeeService(IUnitOfWork uow)
: base(uow)
{
var store = new UserStore<Employee>(Uow.GetDbContext());
_userManager = new ApplicationUserManager(store);
}
}
Anyone knows what I'm doing wrong?
(Can provide more code if more information is needed)
EDIT
Exception message & stacktrace:
exceptionMessage: "None of the constructors found with
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type
'AngularMVC.Services.EmployeeService' can be invoked with the
available services and parameters: Cannot resolve parameter
'AngularMVC.DAL.ApplicationUserManager userManager' of constructor
'Void .ctor(AngularMVC.DAL.IUnitOfWork,
AngularMVC.DAL.ApplicationUserManager)'." exceptionType:
"Autofac.Core.DependencyResolutionException" stackTrace: " at
Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext
context, IEnumerable1 parameters) at
Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1
parameters) at Autofac.Core.Resolving.InstanceLookup.Execute() at
Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope
currentOperationScope, IComponentRegistration registration,
IEnumerable1 parameters) at
Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration
registration, IEnumerable1 parameters) at
Autofac.Core.Activators.Reflection.AutowiringParameter.<>c__DisplayClass2.b__0()
at
Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()
at
Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext
context, IEnumerable1 parameters) at
Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1
parameters) at Autofac.Core.Resolving.InstanceLookup.Execute() at
Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope
currentOperationScope, IComponentRegistration registration,
IEnumerable1 parameters) at
Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration
registration, IEnumerable1 parameters) at
Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration
registration, IEnumerable1 parameters) at
Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration
registration, IEnumerable1 parameters) at
Autofac.ResolutionExtensions.TryResolveService(IComponentContext
context, Service service, IEnumerable1 parameters, Object& instance)
at
Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext
context, Service service, IEnumerable1 parameters) at
Autofac.ResolutionExtensions.ResolveOptional(IComponentContext
context, Type serviceType, IEnumerable1 parameters) at
Autofac.ResolutionExtensions.ResolveOptional(IComponentContext
context, Type serviceType) at
Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type
serviceType) at
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage
request, Type controllerType, Func1& activator) at
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage
request, HttpControllerDescriptor controllerDescriptor, Type
controllerType)"
This is how I have registered ApplicationUserManager in Autofac, which works for all my applications.
builder.Register(c => HttpContext.Current.GetOwinContext().GetUserManager).As<ApplicationUserManager>();
This will say to Autofac that when I ask for an ApplicationUserManager, please get the UserManager from the OwinContext in my Current HttpContext.
This takes the logic and the dependecy on an OwinContext and HttpContext out of the classes, and makes the code much nicer to work with.
You can also do the same for an IAuthenticationManager, to remove your OwinContext dependency also with
builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();

Categories

Resources