web-dev-qa-db-ja.com

StructureMapを使用してASP.NETIdentityApplicationUserManagerを構成する方法

プロジェクトでasp.netIDを使用し、DIフレームワークとしてstructuremapを使用しています。問題は、コンストラクターインジェクションを使用すると、ApplicationUserManagerがそのメンバーのすべてを構成していないことです(例:TokenProvider、.。

これは私のApplicationUserManagerクラスです:

public class ApplicationUserManager : UserManager<User, long>
{
    public ApplicationUserManager(IUserStore<User, long> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new CustomUserStore(context.Get<InsuranceManagementContext>()));

        // Configure the application user manager
        manager.UserValidator = new UserValidator<User, long>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = false
        };

        manager.PasswordValidator = new PasswordValidator
        {
            RequireDigit = true,
            RequiredLength = 8,
            RequireLowercase = false,
            RequireNonLetterOrDigit = true,
            RequireUppercase = false
        };

        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<User, long>(dataProtectionProvider.Create("TEST"));
        }

        return manager;
    }
}

これはStartup.Authクラスです:

public partial class Startup
{
    // For more information on configuring authentication, please visit http://go.Microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(InsuranceManagementContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            ExpireTimeSpan = TimeSpan.FromHours(2.0),
            AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
        });
    }
}

とその私のAccountController:

public class AccountController : BaseController
{
    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

    public AccountController(ApplicationUserManager userManager)
    {
        UserManager = userManager;
    }
}

私の質問は、Structuremapを使用してApplicationUserManagerを構成するにはどうすればよいですか?私がそれを以下のコードとして設定した場合、それは機能しますが、それが良い解決策であるかどうかはわかりません:

ObjectFactory.Initialize(x =>
{
     ...
     x.For<ApplicationUserManager>().Use(() => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>());
     ...
});

より良い解決策があるかどうか、そしてそれが大丈夫なら、それにとって最良の寿命は何ですか? HttpContextScope、シングルトン、...?

9
Mohammad Zare

このためのStructureMap構成を作成する前に、手動で作成する方法、つまり、実際にすべてを自分で「更新」するかどうかを知っておくと役立ちます。

UserManagerはIUserStoreに依存しており、そのEntityFramework実装(UserStore)はDbContextに依存しています。すべてを手動で行うと、次のようになります。

var dbContext = new IdentityDbContext("Your ConnectionString Name");
var userStore = new UserStore<IdentityUser>(dbContext);
var userManager = new UserManager<IdentityUser>(userStore);

(カスタムユーザーを使用している場合は、IdentityUserをカスタムユーザーに置き換えます)

次に、次のようにUserManagerを構成できます。

userManager.PasswordValidator = new PasswordValidator
{
    RequiredLength = 6
};

UserManagerの構成に関する最も複雑な部分は、UserTokenProvider(データ保護APIを使用)に関連しています。手動で行うと、 次のようになります

var dataProtectionProvider = new DpapiDataProtectionProvider("Application name");
var dataProtector = dataProtectionProvider.Create("Purpose");
userManager.UserTokenProvider = new DataProtectorTokenProvider<IdentityUser>(dataProtector);

次に、StructureMapレジストリの例を示します(この例から推定して、独自のニーズに適合させることができます)。

 public DefaultRegistry() {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
                scan.With(new ControllerConvention());
            });


        For<IUserStore<IdentityUser>>()
            .Use<UserStore<IdentityUser>>()
            .Ctor<DbContext>()
            .Is<IdentityDbContext>(cfg => cfg.SelectConstructor(() => new IdentityDbContext("connection string")).Ctor<string>().Is("IdentitySetupWithStructureMap"));

        ForConcreteType<UserManager<IdentityUser>>()
            .Configure
            .SetProperty(userManager => userManager.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6
            })
            .SetProperty(userManager => userManager.UserValidator = new UserValidator<IdentityUser>(userManager));                
    } 

私はブログを書きました これについての投稿 、それはこの構成につながるプロセスを説明します、 MVCプロジェクトのgithubの例へのリンク ここで、この構成を使用します、ユーザーを作成、一覧表示、削除できます。

6
Rui