FormsAuthenticationの非常に単純な例を実装しようとしています。それは現実の生活ではありませんが、問題を引き起こしました。アプリケーションレベルのシングルトンとなることを目的としたAuthenticationServiceは、2回インスタンス化されているように見えます。
コードは次のとおりです。
public class User : IUserIdentity
{
public string UserName { get; set; }
public IEnumerable<string> Claims { get; set; }
}
public interface IAuthenticationService
{
Guid GetIdentifier(string username, string password);
}
public class AuthenticationService : IUserMapper, IAuthenticationService
{
public readonly Guid Identifier = Guid.NewGuid();
private readonly string Username = "admin";
private readonly string Password = "x";
public Guid GetIdentifier(string username, string password)
{
return (username == Username && password == Password) ? Identifier : Guid.Empty;
}
public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context)
{
return (identifier == Identifier) ? new User { UserName = "admin" } : null;
}
}
public class MyBootstrapper : DefaultNancyBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
base.ConfigureApplicationContainer(container);
container.Register<IAuthenticationService, AuthenticationService>().AsSingleton();
}
}
上記のコードは、私が次のように使用してLoginModule
います。AuthenticationService
モジュールのコンストラクターを介して、アプリケーションレベルのシングルトンインスタンスを注入していることに注意してください。
public LoginModule(IAuthenticationService authenticationService)
{
Post["/login"] = _ =>
{
var identifier = authenticationService.GetIdentifier(
(string) Form.Username,
(string) Form.Password);
if (identifier.IsEmpty())
{
return Context.GetRedirect("~/login?error=true");
}
return this.LoginAndRedirect(identifier);
};
}
何が起こるべきかというと、ユーザーPOSTs
がユーザー名とパスワードを入力すると、これらはメソッドAuthenticationService
を介してチェックされます。GetIdentifier(..)
資格情報が一致する場合、単一のGUID
識別子が返されます。これは、フィールドとして作成され、アプリケーションの起動時にシングルトンが最初にインスタンス化されるときに1回設定GUID
されるため、常に同じになります。readonly
AuthenticationService
ただし、そうではありません。代わりに、の2つの異なるインスタンスが作成されます。1つはコンストラクターにAuthenticationService
挿入されてメソッドを呼び出すために使用され、もう1つはナンシーがメソッドを呼び出すために使用します。LoginModule
GetIdentifier(..)
IUserIdentity.GetUserFromIdentifier(..)
これらの2つのインスタンスは異なるGUID
識別子を持っているため、GetUserFromIdentifier(..)
メソッドは常にnullを返します。
実装されていない標準のシングルトンサービスをテストしましたがIUserMapper
、期待どおりに機能し、インスタンスは1つだけ作成されます。
したがって、ナンシーはIUserMapper
シングルトンを2回インスタンス化しているようです。1回はFormsAuthentication中に内部で使用するため、もう1回はLoginModule
コンストラクターに注入するためです。
私の間違いを見つけられますか?
ありがとう