简体   繁体   English

使用ASP.NET Identity 2.2.1设置简单注入器

[英]Setup Simple Injector with ASP.NET Identity 2.2.1

So I've been trying to setup ASP.NET Identity 2.2.1 and I keep hitting roadblocks. 所以我一直在尝试设置ASP.NET Identity 2.2.1,并且我一直在遇到障碍。 For being something that is supposed to be auto-generated by the framework it sure seems complicated to configure. 对于应该由框架自动生成的东西,配置肯定看起来很复杂。 I think I'm almost there but I'm still having issues setting up IoC with Simple Injector. 我想我差不多了,但我仍然遇到使用Simple Injector设置IoC的问题。

I've been reading through other StackOverflow questions and blogs about these issues. 我一直在阅读有关这些问题的其他StackOverflow问题和博客。 Most of them seem out of date because they deal with ASP.NET Identity 1.0. 它们中的大多数似乎都已过时,因为它们处理的是ASP.NET Identity 1.0。 There's even been enough changes from 2.0 to 2.2.1 I've run into some issues with out of date solutions. 甚至有足够的变化从2.0到2.2.1我遇到了一些过时解决方案的问题。 Or the solutions deal with other IoC frameworks and I just can't translate them to Simple Injector. 或者解决方案处理其他IoC框架,我无法将它们转换为Simple Injector。 I've used other IoC Frameworks but I'm new to Simple Injector. 我已经使用了其他IoC框架,但我是Simple Injector的新手。

UPDATE - Ric .Net's first link in his comment was very helpful. 更新 - Ric .Net在他的评论中的第一个链接非常有帮助。 I've reformatted my work to fit his suggestions and I think I'm almost there. 我已经重新格式化我的工作以适应他的建议,我想我几乎就在那里。 But I'm still having one issue. 但我还有一个问题。 I've completed replaced the previous code with the code below. 我已经用以下代码替换了以前的代码。

1) I updated ApplicationDbContext : 1)我更新了ApplicationDbContext

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

2) I removed the Create() method from ApplicationUserManager and moved it into a class that initializes all of my Simple Injector code: 2)我从ApplicationUserManager中删除了Create()方法并将其移动到初始化所有Simple Injector代码的类中:

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) I changed the Configuration method in Startup.cs : 3)我更改了Startup.cs中的Configuration方法:

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

4) I updated ConfigureAuth in Configure.Auth.cs : 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) Then I removed the default constructor and UserManager property from AccountsController. 5)然后我从AccountsController中删除了默认构造函数和UserManager属性。

The problem I'm having now is that since ASP.NET Identity 2.0, they have added the parameter ISecureDataFormat<AuthenticationTicket> accessTokenFormat to the AccountsController constructor. 我现在遇到的问题是,自ASP.NET Identity 2.0以来,他们已将参数ISecureDataFormat<AuthenticationTicket> accessTokenFormat到AccountsController构造函数中。

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

So now, how do I add DI for ISecureDataFormat<AuthenticationTicket> in Simple Injector? 那么现在,如何在Simple Injector中为ISecureDataFormat<AuthenticationTicket>添加DI?

So between the help Ric .Net (which I've posted above as part of the question) and Lucas Teles answer in another question I've finally got my answer. 所以在帮助Ric .Net (我在上面作为问题的一部分发布)和Lucas Teles在另一个问题中回答我终于得到了答案。 Lucas suggested adding these lines to my Simple Injector setup: 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);

So now my container building method looks like this: 所以现在我的容器构建方法如下所示:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM