你如何抽象页面会话属性?

How do you abstract page session properties?

我在关注这个example

示例代码:

public class Global : HttpApplication
{
    private Poster _posterDetails; 
    private Posting _postingDetails;
    private Property _propertyDetails;
    protected void Application_PostRequestHandlerExecute(object sender, EventArgs e)
    {
        if (HttpContext.Current.Session == null) return;
        _posterDetails = HttpContext.Current.Session["Poster"] as Poster;
        _postingDetails = HttpContext.Current.Session["Posting"] as Posting;
        _propertyDetails = HttpContext.Current.Session["Property"] as Property;
    }
}

这些会话变量散布在整个应用程序中,我需要抽象化它们的检索。比如说,稍后我从数据库而不是当前会话中获取它们。

Session被烤成PageContext。我如何将该依赖项注入到可能的当前 属性 getter.

的具体实现中

不确定这是否是您要问的...我经常做的是创建服务:

public 接口 ISessionService { 对象获取(字符串键);

void Save(string key, object value);

}

然后我实现这个,它调用 HttpContext.Current.Session[key] 和 returns 值。创建一个 Get<T>(string key) 到 return 的对象也不难。打破你所有的依赖来使用它(这是困难的部分)。

没有无缝的方法来打破依赖...它必须通过手动更改。

围绕 HttpContext 创建抽象:

public interface IHttpContextFactory
{
    HttpContextBase Create();
}

public class HttpContextFactory
    : IHttpContextFactory
{
    public HttpContextBase Create()
    {
        return new HttpContextWrapper(HttpContext.Current);
    }
}

然后将其注入到专门用于这些设置的服务中。

public interface ISettings
{
    T GetValue<T>(string key);
    void SetValue<T>(string key, T value);
}

public class ContextSettings
    : ISettings
{
    private readonly IHttpContextFactory httpContextFactory;
    private HttpContextBase context;

    public RequestCache(
        IHttpContextFactory httpContextFactory
        )
    {
        if (httpContextFactory == null)
            throw new ArgumentNullException("httpContextFactory");

        this.httpContextFactory = httpContextFactory;
    }

    protected HttpContextBase Context
    {
        get 
        {
            if (this.context == null)
            {
                this.context = this.httpContextFactory.Create();
            }
            return context;
        }
    }

    public virtual T GetValue<T>(string key)
    {
        if (this.Context.Session.Contains(key))
        {
            return (T)this.Context.Session[key];
        }
        return default(T);
    }

    public virtual void SetValue<T>(string key, T value)
    {
        this.Context.Session[key] = value;
    }
}

以后可以通过实现 ISettings 并提供不同的构造函数依赖项,用另一种存储机制替换该服务。请注意,更改构造函数签名不需要不同的接口。

就是说,您应该提供另一种服务(或者可能不止一种)将 ISettings 作为依赖项,以便您可以创建显式属性。您的目标应该是为特定目的提供集中的相关属性集。您的应用程序也不必知道 属性 的类型来检索其值 - 它应该只调用隐藏这些详细信息的 属性。

public class SomeSettingsService: ISomeSettingsService
{
    private readonly ISettings settings;

    public SomeSettingsService(ISettings settings)
    {
        if (settings == null)
            throw new ArgumentNullException("settings");
        this.settings = settings;
    }

    public Poster Poster
    {
        get { return this.settings.GetValue<Poster>("Poster"); }
        set { this.settings.SetValue<Poster>("Poster", value); }
    }

    public Posting Posting
    {
        get { return this.settings.GetValue<Posting>("Posting"); }
        set { this.settings.SetValue<Posting>("Posting", value); }
    }

    public Property Property
    {
        get { return this.settings.GetValue<Property>("Property"); }
        set { this.settings.SetValue<Property>("Property", value); }
    }
}