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

By Tony Mackay  02 February 2015

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 Createmethod 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 SignInManagerUserManager, 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.

最新文章

  1. 使用静态函数impl模式做接口
  2. Linux中exit与_exit的区别
  3. WebAdaptor Object reference not set to an instance of an object.
  4. css 全局 兼容性问题
  5. 整理常用的iOS第三方资源
  6. java获取获得Timestamp类型的当前系统时间
  7. POJ 2533 Longest Ordered Subsequence(LIS模版题)
  8. Least_squares 最小二乘法
  9. stream的Read、Write方法实例
  10. 学c语言做练习之文件
  11. solr创建新的Core
  12. js简易猜数字
  13. 谈谈.NET,Java,php
  14. echarts pie 图表当名称太长时
  15. 使用pymysql
  16. Java基础-SSM之mybatis的树形控件(自关联)
  17. 安装QT的时候出现PATH_MAX错误
  18. 快捷键&amp;小技巧
  19. storm trident merger
  20. java动态代理中的invoke方法是如何被自动调用的(转)

热门文章

  1. 利用sphinx为python项目生成API文档
  2. css权重计算方法浅谈
  3. Win10全屏看视频时任务栏不隐藏
  4. Java 加解密技术系列文章
  5. [django]手动数据库备份
  6. [No00009F]CMD在执行命令时的中断快捷键
  7. 前端之jquery
  8. 如何将网页的title前面的图标替换成自己的图标
  9. 理解ASP.NET MVC的DependencyResolver组件
  10. eclipse直接访问数据库