简体   繁体   English

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

[英]Service locator pattern and logged in user

I'm adjusting my web application layers in a way to make the code more testable. 我正在调整Web应用程序层,以使代码更具可测试性。

Currently the UI talks to a service locator passing in an interface, this returns the appropriate object based on that type: 当前,UI与通过接口传递的服务定位器进行对话,这将基于该类型返回适当的对象:

ServiceLocator.Get<ISomeService>().ListStuff(arg1, arg2);

Internally, services are instantiated with an instance of IServiceContext and cached. 在内部,服务使用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) { }

I'm happy with the concept and it appears to be rugged enough, my only issue is I want to make the current logged in user available in the ServiceContext but unsure the best way to achieve it. 我对这个概念感到满意,它看起来足够坚固,我唯一的问题是我想让当前登录的用户在ServiceContext可用,但不确定实现它的最佳方法。

My thoughts travel along these potential options: 我的想法遵循以下潜在选择:

  1. Keep a simple method in the ServiceLocator that handles getting the users session and injects it into the services as requests for them come in. ServiceLocator中保留一个简单的方法,该方法处理获取用户会话,并在对用户的请求进入时将其注入服务中。
  2. Move getting the current user out of the IServiceContext and into the ServiceBase base class of each service. 将当前用户移出IServiceContext并移到每个服务的ServiceBase基类中。
  3. Stop doing this and make each service that needs a user dependent on it. 停止这样做,并使需要用户的每个服务都依赖于此。

I appreciate any suggestions, I understand this question my not be in the true spirit of the site. 我感谢任何建议,我理解这个问题,并非本网站的真正精神。 I have managed 4 days of trial and error to get to this point, just need the last piece of this puzzle. 我已经经过4天的反复试验才能做到这一点,只需要这个难题的最后一步即可。

There's probably many solutions, and I'm not fully sure I understand your question but I'll try to help anyway. 可能有很多解决方案,但我不确定我是否完全理解您的问题,但是无论如何我都会尽力提供帮助。

Whenever I need the current user I make a call to static utility class right in the context of the code that uses it. 每当需要当前用户时,我都会在使用它的代码上下文中立即调用静态实用程序类。 This way I eliminate the possibility of stale information. 这样我就消除了过时信息的可能性。

You could make a class that implements IUser like 您可以创建一个实现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; } }
}

And then maybe: 然后也许:

public class ServiceContext : IServiceContext
{
    IUser CurrentUser { get { return new User(); } }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM