Matthew Flynn
Matthew Flynn

Reputation: 3931

Microsoft Unity DI with Identity

I've trawled through all the questions on SO but can't seem to work out what i'm doing wrong here.

I have the following UserService

   public class UserService : BaseService
    {
        private readonly Func<UserManager<ApplicationUser>> _userManagerFactory;
        private readonly Func<RoleManager<IdentityRole>> _roleManagerFactory;

        public UserService(Func<UserManager<ApplicationUser>> userManagerFactory, Func<RoleManager<IdentityRole>> roleManagerFactory)
        {
            _userManagerFactory = userManagerFactory;
            _roleManagerFactory = roleManagerFactory;
        }

and in my accounts controller i inject as follows;

public class AccountsController : ApiController
{
    [Dependency]
    public UserService UserService { get; set; }

Now in my UnityConfig.cs I set the DI as follows;

var userInjectionConstructor = new InjectionConstructor(new MyDataContext());
            //container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(userInjectionConstructor);
            container.RegisterType<UserManager<ApplicationUser>, ApplicationUserManager>();
            container.RegisterType<IRoleStore<IdentityRole, string>, RoleStore<IdentityRole>>(userInjectionConstructor);

Where the ApplicationUserManager is as follows;

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var container = (IUnityContainer)Startup.HttpConfiguration.DependencyResolver.GetService(typeof(IUnityContainer));
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(new MyDataContext()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}

This compiles and runs, however, i get the error when it tries to resolve the DI;

Resolution of the dependency failed, type = "Microsoft.AspNet.Identity.UserManager1[CCS.Core.ApplicationUser]", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The current type, Microsoft.AspNet.Identity.IUserStore1[CCS.Core.ApplicationUser], is an interface and cannot be constructed. Are you missing a type mapping?

Now this issue was raised because if I use the following;

var userInjectionConstructor = new InjectionConstructor(new MyDataContext());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(userInjectionConstructor);

Then the DI works, however, none of the ApplicationUserManager setup is there (token providers etc).

Now the ApplicationUserManager.Create call is Static so I assume I'm going to have to move this into the constructor for the DI?

Can anyone explain what I'm dong wrong here and how to resolve?

Upvotes: 0

Views: 677

Answers (1)

Habbex
Habbex

Reputation: 21

Have an other problem which is getting users with roles names, anyway when trying to solve this problem I stumbled on this blog which explains perfectly how to inject http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/.

Good luck mate!

Upvotes: 1

Related Questions