服务定位器模式和登录用户

时间:2013-01-19 10:13:37

标签: c# design-patterns service-locator

我正在调整我的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中的当前登录用户可用,但不确定实现它的最佳方式。

我的想法沿着这些潜在的选择:

  1. ServiceLocator中保留一个简单的方法,用于处理获取用户会话并在请求进入服务时将其注入服务。
  2. 将当前用户移出IServiceContext并进入每项服务的ServiceBase基类。
  3. 停止这样做并使每个需要用户依赖它的服务。
  4. 我感谢任何建议,我理解这个问题我不是真正的网站精神。 我已经管理了4天的试验和错误才能达到这一点,只需要最后一块这个难题。

1 个答案:

答案 0 :(得分:0)

可能有很多解决方案,我不完全确定我理解你的问题,但无论如何我都会尽力帮助。

每当我需要当前用户时,我就会在使用它的代码的上下文中调用静态实用程序类。这样我就消除了陈旧信息的可能性。

你可以创建一个实现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(); } }
}