我正在尝试实现一个非常简单的FormsAuthentication示例。这不是现实生活,但却引发了一个问题。 AuthenticationService旨在成为应用程序级单例,似乎实例化了两次。
以下是代码:
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
标识符。此GUID
将始终相同,因为它创建为readonly
字段,因此在应用程序启动时首次实例化单例AuthenticationService
时设置一次。
但事实并非如此。而是创建AuthenticationService
的两个不同实例,一个注入LoginModule
构造函数并用于调用GetIdentifier(..)
方法,另一个实例由Nancy用来调用IUserIdentity.GetUserFromIdentifier(..)
方法。
这两个实例具有不同的GUID
标识符,因此GetUserFromIdentifier(..)
方法始终返回null。
我测试过一个没有实现IUserMapper
的标准单件服务,它按预期工作,只创建了一个实例。
所以看起来Nancy实例化IUserMapper
单例两次,一次是在FormsAuthentication期间自己内部使用,一次是注入我的LoginModule
构造函数!
你能发现我的错误吗?
由于
答案 0 :(得分:1)
这可能是因为你使用了不同的界面,所以你有一个单例用于请求IUsernameMapper的东西,另一个用于请求IAuthenticationService的东西。
你可以:
我问你为什么要这样做,而不是仅使用内置的表格auth?