【问题标题】:Setup Simple Injector with ASP.NET Identity 2.2.1使用 ASP.NET Identity 2.2.1 设置简单注入器
【发布时间】:2017-03-10 17:27:33
【问题描述】:

所以我一直在尝试设置 ASP.NET Identity 2.2.1,但一直遇到障碍。对于应该由框架自动生成的东西来说,配置起来确实很复杂。我想我快到了,但我仍然在使用 Simple Injector 设置 IoC 时遇到问题。

我一直在阅读有关这些问题的其他 StackOverflow 问题和博客。它们中的大多数似乎已经过时,因为它们处理的是 ASP.NET Identity 1.0。从 2.0 到 2.2.1 甚至发生了足够多的变化,我遇到了一些过时解决方案的问题。或者解决方案处理其他 IoC 框架,我无法将它们转换为 Simple Injector。我使用过其他 IoC 框架,但我是 Simple Injector 的新手。

更新 - Ric .Net's first link in his comment 非常有帮助。我已经重新格式化了我的工作以适应他的建议,我想我快到了。但我仍然有一个问题。我已经用下面的代码替换了之前的代码。

1) 我更新了 ApplicationDbContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(string connectionstring)
        : base(connectionstring, throwIfV1Schema: false)
    {
    }
}

2) 我从 ApplicationUserManager 中删除了 Create() 方法,并将它移到了一个初始化所有简单注入器代码的类中:

public static class SimpleInjectorInitializer
{
    public static Container Initialize(IAppBuilder app)
    {
        var container = GetInitializeContainer(app);

        container.Verify();

        DependencyResolver.SetResolver(
            new SimpleInjectorDependencyResolver(container));

        return container;
    }

    public static Container GetInitializeContainer(
              IAppBuilder app)
    {
        var container = new Container();

        container.RegisterSingle<IAppBuilder>(app);

        container.RegisterPerWebRequest<
               ApplicationUserManager>();

        container.RegisterPerWebRequest<ApplicationDbContext>(() 
          => new ApplicationDbContext(
           "Your constring goes here"));

        container.RegisterPerWebRequest<IUserStore<
          ApplicationUser>>(() => 
            new UserStore<ApplicationUser>(
              container.GetInstance<ApplicationDbContext>()));

        container.RegisterInitializer<ApplicationUserManager>(
            manager => InitializeUserManager(manager, app));

        container.RegisterMvcControllers(
                Assembly.GetExecutingAssembly());

        return container;
    }

    private static void InitializeUserManager(
        ApplicationUserManager manager, IAppBuilder app)
    {
        manager.UserValidator = 
         new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        //Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator()
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = false,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

        var dataProtectionProvider = 
             app.GetDataProtectionProvider();

        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = 
             new DataProtectorTokenProvider<ApplicationUser>(
              dataProtectionProvider.Create("ASP.NET Identity"));
        }
    }
}

3) 我在Startup.cs中更改了Configuration方法:

public void Configuration(IAppBuilder app)
{
    var container = SimpleInjectorInitializer.Initialize(app);
    ConfigureAuth(app, container);
}

4) 我在 Configure.Auth.cs 中更新了 ConfigureAuth:

public void ConfigureAuth(IAppBuilder app, Container container)
{
    // Configure the db context and user manager to use a single instance per request
    //app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext(container.GetInstance<ApplicationUserManager>);
    // Rest of code here ...

5) 然后我从 AccountsController 中删除了默认构造函数和 UserManager 属性。

我现在遇到的问题是,从 ASP.NET Identity 2.0 开始,他们已将参数 ISecureDataFormat&lt;AuthenticationTicket&gt; accessTokenFormat 添加到 AccountsController 构造函数中。

public AccountController(ApplicationUserManager userManager, 
    ISecureDataFormat<AuthenticationTicket> accessTokenFormat)

那么现在,如何在 Simple Injector 中为 ISecureDataFormat&lt;AuthenticationTicket&gt; 添加 DI?

【问题讨论】:

  • 你读过this 了吗?它没有讨论“IdentityFactoryOptions”,但必须提供一些指导。另请参阅this 以获得比您提到的工厂更好的方法。
  • 你读过this吗?您应该将 IdentityFactoryOptions 注册为作用域或单例。不,真正违反最佳协议的并不是你;它是 Identity Feamework,带有非常糟糕的 Visual Studio 模板。
  • Here is a walkthrough 介绍了如何重构默认 MVC 5 模板以与 Autofac、SimpleInjector 或 Unity 集成。
  • 感谢大家的帮助和cmets。 @Ric.Net - 感谢您的第一个链接。这很有帮助。这种方式似乎比我之前拼凑的方式要清晰得多。不过,我仍然遇到了一个小问题。
  • @Steven - 我见过,但没有帮助。很高兴我不是唯一一个质疑 Identity Framework 的 VS 模板的人。

标签: c# asp.net asp.net-mvc asp.net-identity simple-injector


【解决方案1】:

所以在Ric .Net(我已在上面作为问题的一部分发布)和Lucas Teles answer in another question 之间的帮助之间,我终于得到了答案。 Lucas 建议将这些行添加到我的 Simple Injector 设置中:

container.Register<ISecureDataFormat<AuthenticationTicket>,
    SecureDataFormat<AuthenticationTicket>>(Lifestyle.Scoped);
container.Register<ITextEncoder, Base64UrlTextEncoder>(Lifestyle.Scoped);
container.Register<IDataSerializer<AuthenticationTicket>, TicketSerializer>(
    Lifestyle.Scoped);
container.Register<IDataProtector>(
    () => new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider()
        .Create("ASP.NET Identity"),
    Lifestyle.Scoped);

所以现在我的容器构建方法是这样的:

public static Container GetInitializeContainer(IAppBuilder app)
{
    var container = new Container();

    // IoC for ASP.NET Identity
    container.RegisterSingleton<IAppBuilder>(app);
    container.Register<ApplicationUserManager>(Lifestyle.Scoped);
    container.Register<ApplicationDbContext>(
        () => new ApplicationDbContext("Your constring goes here"),
        Lifestyle.Scoped);
    container.Register<IUserStore<ApplicationUser>>(
        () => new UserStore<ApplicationUser>(
            container.GetInstance<ApplicationDbContext>()),
        Lifestyle.Scoped);
    container.RegisterInitializer<ApplicationUserManager>(
        manager => InitializeUserManager(manager, app));
    // Setup for ISecureDataFormat
    container.Register<ISecureDataFormat<AuthenticationTicket>, 
        SecureDataFormat<AuthenticationTicket>>(Lifestyle.Scoped);
    container.Register<ITextEncoder, Base64UrlTextEncoder>(Lifestyle.Scoped);
    container.Register<IDataSerializer<AuthenticationTicket>, 
        TicketSerializer>(Lifestyle.Scoped);
    container.Register<IDataProtector>(
        () => new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider()
            .Create("ASP.NET Identity"),
        Lifestyle.Scoped);

    // Register all controllers
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

    return container;
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-04-21
  • 2014-10-22
  • 1970-01-01
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多