Configuring Autofac to work with the ASP.NET Identity Framework in MVC 5
https://developingsoftware.com/configuring-autofac-to-work-with-the-aspnet-identity-framework-in-mvc-5
Configuring Autofac to work with the ASP.NET Identity Framework in MVC 5
This post will show you how to modify the default MVC 5 template, so that it uses Autofac to inject the ASP.NET Identity dependencies into the Account Controller.
This post assumes you already know how to create a new ASP.NET MVC 5 project, if not, see the post: How to Create an ASP.NET MVC 5 Web Application.
Step 1: Create new ASP.NET MVC 5 application and Install Dependencies
First create a new MVC 5 project using the default settings. I have named the project AutofacIdentityExample, which you can download from here.
Once created, use the package manager console to update the existing dependencies with the following command:
Update-Package
Now install the Autofac dependencies by running the following commands:
Install-Package Autofac.Mvc5
Install-Package Autofac.Mvc5.Owin
Step 2: Create a custom ApplicationUserStore
Open the IdentityConfig
file and then create the following class:
public class ApplicationUserStore : UserStore<ApplicationUser>
{
public ApplicationUserStore(ApplicationDbContext context)
: base(context)
{
}
}
We will use this class in the next step when configuring Autofac.
Step 3: Modify the Startup class to register dependencies with Autofac
Modify the Configuration
method so that it looks like the following:
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
// REGISTER DEPENDENCIES
builder.RegisterType<ApplicationDbContext>().AsSelf().InstancePerRequest();
builder.RegisterType<ApplicationUserStore>().As<IUserStore<ApplicationUser>>().InstancePerRequest();
builder.RegisterType<ApplicationUserManager>().AsSelf().InstancePerRequest();
builder.RegisterType<ApplicationSignInManager>().AsSelf().InstancePerRequest();
builder.Register<IAuthenticationManager>(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerRequest();
builder.Register<IDataProtectionProvider>(c => app.GetDataProtectionProvider()).InstancePerRequest();
// REGISTER CONTROLLERS SO DEPENDENCIES ARE CONSTRUCTOR INJECTED
builder.RegisterControllers(typeof(MvcApplication).Assembly);
// BUILD THE CONTAINER
var container = builder.Build();
// REPLACE THE MVC DEPENDENCY RESOLVER WITH AUTOFAC
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// REGISTER WITH OWIN
app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
ConfigureAuth(app);
}
Step 4: Modify the Startup.Auth class
The next step is to comment out the code that is used to register the dependencies manually through OWIN. Open the Startup.Auth
class and comment out the following lines of the ConfigureAuth
method:
// Configure the db context, user manager and signin manager to use a single instance per request
//app.CreatePerOwinContext(ApplicationDbContext.Create);
//app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
//app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
Step 5: Modify the ApplicationUserManager
In this step, we need to move the configuration code from the factory Create
method into the constructor. Change the ApplicationUserManager
class to look like this:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store, IDataProtectionProvider dataProtectionProvider)
: base(store)
{
UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
UserLockoutEnabledByDefault = false;
//DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
//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.
RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
EmailService = new EmailService();
SmsService = new SmsService();
UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
}
As you can see from the code above we have changed the way theDataProtectorTokenProvider
type is resolved, so that it's injected using Autofac. Ideally, you would want to inject the EmailService
and SmsService
as well, but I have left it the way it is for this example.
Step 6: Modify the AccountController
The final step is to modify the AccountController
so that there is only one constructor, and so that the properties that use the Identity framework are no longer resolved using the service locator pattern.
First of all remove the default empty constructor and then change the controller so that there is only one constructor like so:
private readonly ApplicationUserManager _userManager;
private readonly ApplicationSignInManager _signInManager;
private readonly IAuthenticationManager _authManager;
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, IAuthenticationManager authManager)
{
_userManager = userManager;
_signInManager = signInManager;
_authManager = authManager;
}
Now change the properties of the SignInManager
, UserManager
, andAuthenticationManager
so that they are readonly with no service location.
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager;
}
}
private IAuthenticationManager AuthenticationManager
{
get
{
return _authManager;
}
}
Finally, we will let Autofac handle the disposal of objects by removing theDispose
override.
//protected override void Dispose(bool disposing)
//{
// if (disposing)
// {
// if (_userManager != null)
// {
// _userManager.Dispose();
// _userManager = null;
// }
// if (_signInManager != null)
// {
// _signInManager.Dispose();
// _signInManager = null;
// }
// }
// base.Dispose(disposing);
//}
Conclusion
That's all there is to it. Now, if you put a breakpoint on the first line of the constructor, inside the AccountController
, you should see that the dependencies have been injected, and the ASP.NET Identity framework should work as expected.
Download the AutofacIdentityExample project.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)