0

通常我必须从我的 ASP.NET 应用程序的任何部分跨多个请求访问相同的信息。使用下面的示例,我尝试获取当前请求的 URL(我经常忘记需要哪个属性)。我正在尝试提出一种类似于 ASP.NET 处理 HttpContext 的方法。到目前为止,我想出了以下内容:

public interface ICustomContext {
    HttpContextBase Http { get; }
    string Url { get; }
}

public class CustomContext : ICustomContext {
    private readonly HttpContextBase _httpContext;

    public CustomContext(HttpContextBase httpContext) {
        _httpContext = httpContext;
    }

    public HttpContextBase Http {
        get { return _httpContext; }
    }

    public string Url {
        get { return Http.Request.Url.AbsoluteUri; }
    }
}

public class MyContext {
    private static ICustomContext _instance = new CustomContext(new HttpContextWrapper(HttpContext.Current));

    public static ICustomContext Current {
        get { return _instance; }
    }
}

这允许我稍后在我自己的上下文之上添加其他属性。我希望我可以简单地说:

MyContext.Current.Url;

但是,它总是在第一次调用时返回页面的 url。我猜这是某种线程问题,但我不知道如何解决它。

我会很感激帮助。哦,请注意,理想情况下,我希望有一个干净且易于测试的解决方案。

谢谢

4

2 回答 2

0

我认为线索与静态字段一致

private static ICustomContext _instance

尝试将其更改为

public static ICustomContext Current {
        get { return new CustomContext(HttpContext.Current); }
    }
于 2012-08-08T15:10:59.460 回答
0

我找到了一个很好的方法来处理这个。我最初的想法是将实例存储在 HttpContext.Current.Items 集合中(因为每个请求都存在)。然后我意识到,因为我使用 Microsoft Unity 作为我的 Ioc,并且我已经定义了我自己的 LifetimeManager,它将对象存储在 HttpContext.Current.Items 集合中,所以我可以通过说来注册类型:

container.RegisterType<HttpContextBase>(new InjectionFactory(c => {
    return new HttpContextWrapper(HttpContext.Current);
}));
container.RegisterType<ICustomContext, CustomContext>(new PerRequestLifetimeManager<ICustomContext>());

现在我可以像这样定义我的静态属性:

public static ICustomContext Current {
    get { return DependencyResolver.Current.GetService<ICustomContext>(); }
}
于 2012-08-08T18:31:38.993 回答