Inject all dependencies directly into RoleManager and UserManager

- All dependencies for RoleManager and UserManager should be required
- The old calls to GetService inside the constructors will throw instead of
  returning null if left in after PR aspnet/DependencyInjection#87 is merged
This commit is contained in:
Stephen Halter 2014-06-10 16:37:49 -07:00
parent bbb3cf30e1
commit af66fe1611
10 changed files with 83 additions and 47 deletions

View File

@ -21,19 +21,19 @@ namespace Microsoft.AspNet.Identity
/// <summary>
/// Constructor
/// </summary>
/// <param name="services"></param>
/// <param name="store">The IRoleStore is responsible for commiting changes via the UpdateAsync/CreateAsync methods</param>
public RoleManager(IServiceProvider services, IRoleStore<TRole> store)
/// <param name="roleValidator"></param>
public RoleManager(IRoleStore<TRole> store, IRoleValidator<TRole> roleValidator)
{
if (store == null)
{
throw new ArgumentNullException("store");
}
if (services == null)
if (roleValidator == null)
{
throw new ArgumentNullException("services");
throw new ArgumentNullException("roleValidator");
}
RoleValidator = services.GetService<IRoleValidator<TRole>>() ?? new RoleValidator<TRole>();
RoleValidator = roleValidator;
Store = store;
}

View File

@ -32,15 +32,16 @@ namespace Microsoft.AspNet.Identity
/// <summary>
/// Constructor which takes a service provider and user store
/// </summary>
/// <param name="serviceProvider"></param>
/// <param name="store"></param>
/// <param name="optionsAccessor"></param>
public UserManager(IServiceProvider serviceProvider, IUserStore<TUser> store, IOptionsAccessor<IdentityOptions> optionsAccessor)
/// <param name="passwordHasher"></param>
/// <param name="userValidator"></param>
/// <param name="passwordValidator"></param>
/// <param name="claimsIdentityFactory"></param>
public UserManager(IUserStore<TUser> store, IOptionsAccessor<IdentityOptions> optionsAccessor,
IPasswordHasher passwordHasher, IUserValidator<TUser> userValidator,
IPasswordValidator<TUser> passwordValidator, IClaimsIdentityFactory<TUser> claimsIdentityFactory)
{
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
if (store == null)
{
throw new ArgumentNullException("store");
@ -49,12 +50,28 @@ namespace Microsoft.AspNet.Identity
{
throw new ArgumentNullException("optionsAccessor");
}
if (passwordHasher == null)
{
throw new ArgumentNullException("passwordHasher");
}
if (userValidator == null)
{
throw new ArgumentNullException("userValidator");
}
if (passwordValidator == null)
{
throw new ArgumentNullException("passwordValidator");
}
if (claimsIdentityFactory == null)
{
throw new ArgumentNullException("claimsIdentityFactory");
}
Store = store;
Options = optionsAccessor.Options;
PasswordHasher = serviceProvider.GetService<IPasswordHasher>() ?? new PasswordHasher();
UserValidator = serviceProvider.GetService<IUserValidator<TUser>>() ?? new UserValidator<TUser>();
PasswordValidator = serviceProvider.GetService<IPasswordValidator<TUser>>() ?? new PasswordValidator<TUser>();
ClaimsIdentityFactory = serviceProvider.GetService<IClaimsIdentityFactory<TUser>>() ?? new ClaimsIdentityFactory<TUser>();
PasswordHasher = passwordHasher;
UserValidator = userValidator;
PasswordValidator = passwordValidator;
ClaimsIdentityFactory = claimsIdentityFactory;
// TODO: Email/Sms/Token services
}

View File

@ -25,10 +25,10 @@ namespace Microsoft.AspNet.Identity.Entity.Test
{
var services = new ServiceCollection();
services.AddEntityFramework().AddInMemoryStore();
services.AddIdentity<EntityUser, EntityRole>();
services.AddSingleton<IOptionsAccessor<IdentityOptions>, OptionsAccessor<IdentityOptions>>();
services.AddInstance<IdentityContext>(new IdentityContext());
services.AddTransient<IUserStore<EntityUser>, InMemoryUserStore>();
services.AddSingleton<UserManager<EntityUser>>();
var provider = services.BuildServiceProvider();
var manager = provider.GetService<UserManager<EntityUser>>();
Assert.NotNull(manager);

View File

@ -38,6 +38,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
services.AddEntityFramework().AddInMemoryStore();
services.AddTransient<IdentityContext>();
services.AddTransient<IRoleStore<EntityRole>, EntityRoleStore<EntityRole>>();
services.AddTransient<IRoleValidator<EntityRole>, RoleValidator<EntityRole>>();
services.AddSingleton<RoleManager<EntityRole>>();
var provider = services.BuildServiceProvider();
var manager = provider.GetService<RoleManager<EntityRole>>();

View File

@ -14,10 +14,7 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
{
var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices());
services.AddTransient<IUserValidator<IdentityUser>, UserValidator<IdentityUser>>();
services.AddTransient<IPasswordValidator<IdentityUser>, PasswordValidator<IdentityUser>>();
services.AddSingleton<IUserStore<IdentityUser>, InMemoryUserStore<IdentityUser>>();
services.AddSingleton<UserManager<IdentityUser>>();
services.AddIdentity().AddInMemory();
services.SetupOptions<IdentityOptions>(options =>
{
options.Password.RequireDigit = false;
@ -32,9 +29,7 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
protected override RoleManager<IdentityRole> CreateRoleManager()
{
var services = new ServiceCollection();
services.AddTransient<IRoleValidator<IdentityRole>, RoleValidator<IdentityRole>>();
services.AddInstance<IRoleStore<IdentityRole>>(new InMemoryRoleStore<IdentityRole>());
services.AddSingleton<RoleManager<IdentityRole>>();
services.AddIdentity().AddInMemory();
return services.BuildServiceProvider().GetService<RoleManager<IdentityRole>>();
}
}

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Identity.Test
[Fact]
public void RolesQueryableFailWhenStoreNotImplemented()
{
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
var manager = CreateRoleManager(new NoopRoleStore());
Assert.False(manager.SupportsQueryableRoles);
Assert.Throws<NotSupportedException>(() => manager.Roles.Count());
}
@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Identity.Test
[Fact]
public void DisposeAfterDisposeDoesNotThrow()
{
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
var manager = CreateRoleManager(new NoopRoleStore());
manager.Dispose();
manager.Dispose();
}
@ -34,10 +34,10 @@ namespace Microsoft.AspNet.Identity.Test
{
var provider = new ServiceCollection().BuildServiceProvider();
Assert.Throws<ArgumentNullException>("store",
() => new RoleManager<TestRole>(provider, null));
Assert.Throws<ArgumentNullException>("services",
() => new RoleManager<TestRole>(null, new NotImplementedStore()));
var manager = new RoleManager<TestRole>(provider, new NotImplementedStore());
() => new RoleManager<TestRole>(null, new RoleValidator<TestRole>()));
Assert.Throws<ArgumentNullException>("roleValidator",
() => new RoleManager<TestRole>(new NotImplementedStore(), null));
var manager = CreateRoleManager(new NotImplementedStore());
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.CreateAsync(null));
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.UpdateAsync(null));
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.DeleteAsync(null));
@ -48,7 +48,7 @@ namespace Microsoft.AspNet.Identity.Test
[Fact]
public async Task RoleStoreMethodsThrowWhenDisposed()
{
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
var manager = CreateRoleManager(new NoopRoleStore());
manager.Dispose();
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByIdAsync(null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByNameAsync(null));
@ -58,6 +58,11 @@ namespace Microsoft.AspNet.Identity.Test
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.DeleteAsync(null));
}
private static RoleManager<TestRole> CreateRoleManager(IRoleStore<TestRole> roleStore)
{
return new RoleManager<TestRole>(roleStore, new RoleValidator<TestRole>());
}
private class NotImplementedStore : IRoleStore<TestRole>
{
public Task CreateAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken))

View File

@ -15,8 +15,8 @@ namespace Microsoft.AspNet.Identity.Test
public async Task ValidateThrowsWithNull()
{
// Setup
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
var validator = new RoleValidator<TestRole>();
var manager = new RoleManager<TestRole>(new NoopRoleStore(), validator);
// Act
// Assert
@ -30,8 +30,8 @@ namespace Microsoft.AspNet.Identity.Test
public async Task ValidateFailsWithTooShortRoleName(string input)
{
// Setup
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
var validator = new RoleValidator<TestRole>();
var manager = new RoleManager<TestRole>(new NoopRoleStore(), validator);
var user = new TestRole {Name = input};
// Act

View File

@ -21,7 +21,10 @@ namespace Microsoft.AspNet.Identity.Test
{
public IUserStore<TestUser> StorePublic { get { return Store; } }
public TestManager(IServiceProvider provider, IUserStore<TestUser> store, IOptionsAccessor<IdentityOptions> options) : base(provider, store, options) { }
public TestManager(IUserStore<TestUser> store, IOptionsAccessor<IdentityOptions> optionsAccessor,
IPasswordHasher passwordHasher, IUserValidator<TestUser> userValidator,
IPasswordValidator<TestUser> passwordValidator, IClaimsIdentityFactory<TestUser> claimsIdentityFactory)
: base(store, optionsAccessor, passwordHasher, userValidator, passwordValidator, claimsIdentityFactory) { }
}
[Fact]
@ -47,7 +50,6 @@ namespace Microsoft.AspNet.Identity.Test
// Setup
var store = new Mock<IUserStore<TestUser>>();
var user = new TestUser { UserName = "Foo" };
var options = new OptionsAccessor<IdentityOptions>(null);
store.Setup(s => s.CreateAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
@ -65,9 +67,8 @@ namespace Microsoft.AspNet.Identity.Test
// Setup
var store = new Mock<IUserStore<TestUser>>();
var user = new TestUser { UserName = "Foo" };
var options = new OptionsAccessor<IdentityOptions>(null);
store.Setup(s => s.DeleteAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
var userManager = new UserManager<TestUser>(new ServiceCollection().BuildServiceProvider(), store.Object, options);
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
// Act
var result = await userManager.DeleteAsync(user);
@ -420,14 +421,28 @@ namespace Microsoft.AspNet.Identity.Test
[Fact]
public async Task ManagerPublicNullChecks()
{
var provider = new ServiceCollection().BuildServiceProvider();
Assert.Throws<ArgumentNullException>("serviceProvider",
() => new UserManager<TestUser>(null, null, null));
var store = new NotImplementedStore();
var optionsAccessor = new OptionsAccessor<IdentityOptions>(null);
var passwordHasher = new PasswordHasher();
var userValidator = new UserValidator<TestUser>();
var passwordValidator = new PasswordValidator<TestUser>();
var claimsIdentityFactory = new ClaimsIdentityFactory<TestUser>();
Assert.Throws<ArgumentNullException>("store",
() => new UserManager<TestUser>(provider, null, null));
() => new UserManager<TestUser>(null, null, null, null, null, null));
Assert.Throws<ArgumentNullException>("optionsAccessor",
() => new UserManager<TestUser>(provider, new NotImplementedStore(), null));
var manager = new UserManager<TestUser>(provider, new NotImplementedStore(), new OptionsAccessor<IdentityOptions>(null));
() => new UserManager<TestUser>(store, null, null, null, null, null));
Assert.Throws<ArgumentNullException>("passwordHasher",
() => new UserManager<TestUser>(store, optionsAccessor, null, null, null, null));
Assert.Throws<ArgumentNullException>("userValidator",
() => new UserManager<TestUser>(store, optionsAccessor, passwordHasher, null, null, null));
Assert.Throws<ArgumentNullException>("passwordValidator",
() => new UserManager<TestUser>(store, optionsAccessor, passwordHasher, userValidator, null, null));
Assert.Throws<ArgumentNullException>("claimsIdentityFactory",
() => new UserManager<TestUser>(store, optionsAccessor, passwordHasher, userValidator, passwordValidator, null));
var manager = new UserManager<TestUser>(store, optionsAccessor, passwordHasher, userValidator, passwordValidator, claimsIdentityFactory);
Assert.Throws<ArgumentNullException>("value", () => manager.ClaimsIdentityFactory = null);
Assert.Throws<ArgumentNullException>("value", () => manager.PasswordHasher = null);
Assert.Throws<ArgumentNullException>("value", () => manager.Options = null);

View File

@ -8,12 +8,16 @@ namespace Microsoft.AspNet.Identity.Test
{
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IServiceProvider services, IUserStore<ApplicationUser> store, IOptionsAccessor<IdentityOptions> options) : base(services, store, options) { }
public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptionsAccessor<IdentityOptions> options,
IPasswordHasher passwordHasher, IUserValidator<ApplicationUser> userValidator,
IPasswordValidator<ApplicationUser> passwordValidator, IClaimsIdentityFactory<ApplicationUser> claimsIdentityFactory)
: base(store, options, passwordHasher, userValidator, passwordValidator, claimsIdentityFactory) { }
}
public class ApplicationRoleManager : RoleManager<IdentityRole>
{
public ApplicationRoleManager(IServiceProvider services, IRoleStore<IdentityRole> store) : base(services, store) { }
public ApplicationRoleManager(IRoleStore<IdentityRole> store, IRoleValidator<IdentityRole> roleValidator)
: base(store, roleValidator) { }
}
public class ApplicationUser : IdentityUser

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Identity.Test
{
var store = new Mock<IUserStore<TUser>>();
var options = new OptionsAccessor<IdentityOptions>(null);
return new Mock<UserManager<TUser>>(new ServiceCollection().BuildServiceProvider(), store.Object, options);
return new Mock<UserManager<TUser>>(store.Object, options, new PasswordHasher(), new UserValidator<TUser>(), new PasswordValidator<TUser>(), new ClaimsIdentityFactory<TUser>());
}
public static UserManager<TUser> TestUserManager<TUser>() where TUser : class
@ -45,9 +45,8 @@ namespace Microsoft.AspNet.Identity.Test
{
var options = new OptionsAccessor<IdentityOptions>(null);
var validator = new Mock<UserValidator<TUser>>();
var userManager = new UserManager<TUser>(new ServiceCollection().BuildServiceProvider(), store, options);
var userManager = new UserManager<TUser>(store, options, new PasswordHasher(), validator.Object, new PasswordValidator<TUser>(), new ClaimsIdentityFactory<TUser>());
validator.Setup(v => v.ValidateAsync(userManager, It.IsAny<TUser>(), CancellationToken.None)).Returns(Task.FromResult(IdentityResult.Success)).Verifiable();
userManager.UserValidator = validator.Object;
return userManager;
}
}