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> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
/// <param name="services"></param>
/// <param name="store">The IRoleStore is responsible for commiting changes via the UpdateAsync/CreateAsync methods</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) if (store == null)
{ {
throw new ArgumentNullException("store"); 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; Store = store;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Identity.Test
{ {
var store = new Mock<IUserStore<TUser>>(); var store = new Mock<IUserStore<TUser>>();
var options = new OptionsAccessor<IdentityOptions>(null); 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 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 options = new OptionsAccessor<IdentityOptions>(null);
var validator = new Mock<UserValidator<TUser>>(); 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(); validator.Setup(v => v.ValidateAsync(userManager, It.IsAny<TUser>(), CancellationToken.None)).Returns(Task.FromResult(IdentityResult.Success)).Verifiable();
userManager.UserValidator = validator.Object;
return userManager; return userManager;
} }
} }