服务定位器模式和登录用户
本文关键字:登录 用户 模式 定位器 服务 | 更新日期: 2023-09-27 17:54:53
我正在调整我的web应用程序层,以使代码更易于测试。
当前UI与传入接口的服务定位器对话,这将根据该类型返回适当的对象:
ServiceLocator.Get<ISomeService>().ListStuff(arg1, arg2);
在内部,服务使用IServiceContext
的实例实例化并缓存。
private static Lazy<IDictionary<Type, object>> _services = new Lazy<IDictionary<Type, object>>(GetServices);
public interface IServiceContext
{
IConfiguration Configuration { get; }
IUser CurrentUser { get; internal set; }
ILogProvider Log { get; }
ICacheProvider Cache { get; }
IProfilerProvider Profiler { get; }
}
public LogService(IServiceContext serviceContext)
: base(serviceContext) { }
我对这个概念很满意,它看起来足够坚固,我唯一的问题是我想让当前登录的用户在ServiceContext
中可用,但不确定实现它的最佳方法。
我的思绪在这些可能的选择中穿梭:
- 在
ServiceLocator
中保持一个简单的方法,该方法处理获取用户会话并将其注入服务,因为请求他们进来。 - 将获取当前用户从
IServiceContext
移到每个服务的ServiceBase
基类中。 - 停止这样做,让每个需要用户的服务依赖于它。
我感谢任何建议,我明白这个问题不符合网站的真正精神。我已经试错了4天才得出这个结论,只需要解开这个谜题的最后一块。
可能有很多解决方案,我不完全确定我理解你的问题,但我会尽力帮助你。
每当我需要当前用户时,我就在使用它的代码上下文中调用静态实用程序类。这样我就消除了陈旧信息的可能性。
你可以创建一个实现IUser
的类,比如
class User : IUser {
private System.Security.Principal.WindowsIdentity identity;
public User() {
this.identity = identity = System.Security.Principal.WindowsIdentity.GetCurrent();
}
public string UserName { get { return this.identity.Name; } }
}
然后可能是:
public class ServiceContext : IServiceContext
{
IUser CurrentUser { get { return new User(); } }
}