Skip to content

Dependency injection of custom IdentityUser class #11232

Closed
@mmaderic

Description

Hi,

I need help understanding how this could be done.
What I am trying to achieve is dependency injection of UserManager service in unreferenced assembly from main project. Everything is working if built in IdentityUser is used as type, but when trying to do the same with custom one, it can't build the service, no mater what I try.

Here is the execution chain with the built in IdentityUser class that works fine:
Executable project startup class, ConfigureServices method call:

 public void ConfigureServices(IServiceCollection services)
 {     
    // removed other services for brevity
    IdentityServiceLoader.LoadIdentityService(services, Config.GetConnectionString("Identity"));
 }

Executable project is referencing library assembly (application layer) containing implementation of LoadIdentityService method.

LoadIdentityService then loads dynamically another library assembly, containing IIdentityService implementation (infrastructure layer) and calls RegisterIdentityService interface method.

    public sealed class IdentityServiceLoader
    {
        public static void LoadIdentityService(IServiceCollection services, string connectionString)
        {            
            var loader = PluginLoader.CreateFromAssemblyFile(Path.GetFullPath(Const.InfrastructurePath), PluginLoaderOptions.PreferSharedTypes);
            var assembly = loader.LoadDefaultAssembly();

            var serviceType = assembly.GetExportedTypes().Single(x => typeof(IIdentityService).IsAssignableFrom(x));       
            var service = (IIdentityService)Activator.CreateInstance(serviceType);

            service.RegisterIdentityService(services, connectionString);
        }
    }
}

And finally infrastructure layer is implementing identityservice self registration into main project services collection.

     public class IdentityService : IIdentityService
     {
         public void RegisterIdentityService(IServiceCollection services, string connectionString)
         {
            services.AddDbContext<ApplicationIdentityDbContext>(options =>
                options.UseSqlServer(connectionString));

            services.AddIdentity<IdentityUser, IdentityRole>(options =>
                {
                    options.User.RequireUniqueEmail = true;
                    options.Password.RequireNonAlphanumeric = false;
                })
                .AddEntityFrameworkStores<ApplicationIdentityDbContext>()
                .AddDefaultTokenProviders();         
        }
     }

The end user of this dependency injection is the identityservice itself, trying to use the service in its command handler implementation.

public sealed class CreateApplicationUserHandler : ICreateApplicationUserHandler
    {
        private readonly UserManager<IdentityUser> _userManager;
        private readonly IMediator _mediator;

        public CreateApplicationUserHandler(UserManager<IdentityUser> userManager, IMediator mediator)
        {
            _userManager = userManager;
            _mediator = mediator;
        }
    }

If used instead of IdentityUser with custom ApplicationUser (implemented at identity service assembly) it throws this exception:

System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: MediatR.IRequestHandler2[Vigab.Application.Actions.Commands.CreateApplicationUserCommand,System.Guid] Lifetime: Transient ImplementationType: Vigab.Infrastructure.IdentityService.Handlers.Commands.CreateApplicationUserHandler': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Vigab.Infrastructure.IdentityService.ApplicationUser]' while attempting to activate 'Vigab.Infrastructure.IdentityService.Handlers.Commands.CreateApplicationUserHandler'.)

Metadata

Assignees

No one assigned

    Labels

    Needs: Author FeedbackThe author of this issue needs to respond in order for us to continue investigating this issue.area-identityIncludes: Identity and providersquestion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions