In the base template, when creating an asp.net mvc project, the asp.net identity used as the authorization system (by default).

 public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync( UserManager<ApplicationUser> manager) {} } public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store) {} public static ApplicationUserManager Create( IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) {} } public class ApplicationSignInManager : SignInManager<ApplicationUser, string> { public ApplicationSignInManager( ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { } public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) {} public static ApplicationSignInManager Create( IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) {} } public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) {} static ApplicationDbContext() {} public static ApplicationDbContext Create() {} } 

The above classes are used when setting up authorization in the application

 public partial class Startup { public void ConfigureAuth(IAppBuilder app) { // Configure the db context, user manager and role manager to use // a single instance per request app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create); app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); } } 

How in the above code to get rid of a strong dependency - app.CreatePerOwinContext() ?

    2 answers 2

    Let's use Autofac's IoC container for dependency injection.

    Using the Nuget package manager, install the necessary packages:

    We make the following changes to the Startup class:

     private void ConfigureContainer(IAppBuilder app) { var builder = new ContainerBuilder(); // STANDARD MVC SETUP: // Register your MVC controllers. builder.RegisterControllers(typeof(MvcApplication).Assembly); // Run other optional steps, like registering model binders, // web abstractions, etc., then set the dependency resolver // to be Autofac. builder.RegisterType<ApplicationDbContext>().As<DbContext>().InstancePerRequest(); builder.RegisterType<ApplicationSignInManager>() .As<SignInManager<ApplicationUser, string>>().InstancePerRequest(); builder.RegisterType<UserStore<ApplicationUser>>() .As<IUserStore<ApplicationUser>>().InstancePerRequest(); builder.Register<IAuthenticationManager>((c, p) => c.Resolve<IOwinContext>() .Authentication).InstancePerRequest(); var dataProtectionProvider = app.GetDataProtectionProvider(); builder.Register<UserManager<ApplicationUser>>((c, p) => BuildUserManager(c, p, dataProtectionProvider)); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); // OWIN MVC SETUP: // Register the Autofac middleware FIRST, then the Autofac MVC middleware. app.UseAutofacMiddleware(container); app.UseAutofacMvc(); } private UserManager<ApplicationUser> BuildUserManager( IComponentContext context, IEnumerable<Parameter> parameters, IDataProtectionProvider dataProtectionProvider) { var manager = new ApplicationUserManager(context.Resolve<IUserStore<ApplicationUser>>()); // 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, }; // Configure user lockout defaults manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); manager.MaxFailedAccessAttemptsBeforeLockout = 5; // Register two factor authentication providers. // This application uses Phone and Emails as a step of receiving a code // for verifying the user // You can write your own provider and plug it in here. manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser> { MessageFormat = "Your security code is {0}" }); manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser> { Subject = "Security Code", BodyFormat = "Your security code is {0}" }); //manager.EmailService = new EmailService(); //manager.SmsService = new SmsService(); if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>( dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } } 

    Add a call to the ConfigureContainer(IAppBuilder app) method ConfigureContainer(IAppBuilder app) to the Configuration(IAppBuilder app) method Configuration(IAppBuilder app)

     public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); ConfigureContainer(app); } } 

    After the above steps, you can remove the app.CreatePerOwinContext() methods from the ConfigureAuth() method

    it is also necessary to modify the AccountControlle, ManageController :

    1. Remove constructor without parameters.
    2. Delete the following properties: UserManager , SignInManager , AuthenticationManager

    This is how AccountController may look like after making the necessary changes:

     public class AccountController : Controller { private readonly IAuthenticationManager _authenticationManager; private readonly SignInManager<ApplicationUser, string> _signInManager; private readonly UserManager<ApplicationUser> _userManager; public AccountController( UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser, string> signInManager, IAuthenticationManager authenticationManager) { _authenticationManager = authenticationManager; _userManager = userManager; _signInManager = signInManager; } //Прочие необходимые методы } 

    Information sources used:

      String app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); the framework is needed in order to get the ApplicationUserManager object in SecurityStampValidator .

      It is not necessary to leave the code for ApplicationUserManager.Create but you need to teach the framework how to get the ApplicationUserManager instance. If you use a DI container, you can replace it with app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());

      • by and large in the project, everything suited me by default until I began to stratify the application: i.e. ApplicationUser to DAO , ApplicationDbContext to DAL . - Bald
      • Yes, Identity has problems with this - where the ApplicationUser lives, there should be a dependence on EF which is not always desirable. - trailmax