ASP.NET 当前会话对象 - 注入日志逻辑
ASP.NET current Session object - inject log logic
在我正在开发的应用程序中,我们使用了 InProc ASP.NET SessionState 对象。
我想找到一种方法来在某些代码读取或写入 Session 对象时记录消息。
我知道 Item[] 索引,我想我应该以某种方式注入代码..或者继承 HttpSessionState class?
选项、想法、经验...?
您可以创建一个自定义的 SessionStateProvider,您可以从该提供程序中实例化 InProcSessionStateStore 的一个实例,并使用它来完成与会话存储处理相关的所有工作。
并且在这个自定义 SessionStateProvider 中,您可以执行所有的日志记录。
所以这是你必须做的:
创建一个新的class继承SessionStateStoreProviderBaseclass,假设它被命名为"MySessionStateProvider"
实现所有抽象 class 方法。
在 class 的构造函数中,使用反射创建 InProcSessionStateStore class 的实例(ASP.NET 使用它来存储会话状态当为 InProc 配置时 - 你的情况)
将此实例存储在变量中
- 在所有覆盖的方法中使用上述 InProc 实例 class 以执行必要的操作。
- 在 Web.Config
中配置此新提供程序
- 最后但同样重要的是,实施您的日志记录
这是示例代码(以及 link 其他人如何创建自定义提供程序的信息,如果您需要一个包含更多信息的工作示例)。
https://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstatestoreproviderbase(v=vs.110).aspx
http://www.codeproject.com/Articles/102000/ASP-NET-Custom-Session-Store-Provider-compatible-w
Web.Config
<sessionState mode="Custom" customProvider="custom_provider" ... >
<providers>
<add name="custom_provider" type="Xxxx.xxx.MySessionStateProvider"/>
</providers>
</sessionState>
MySessionStateProvider class 代码:
public class MySessionStateProvider : System.Web.SessionState.SessionStateStoreProviderBase {
private readonly SessionStateStoreProviderBase InProcSessionStore;
public MySessionStateProvider() {
var inProcSessionStoreType = typeof(System.Web.SessionState.SessionStateStoreProviderBase).Assembly.GetType("System.Web.SessionState.InProcSessionStateStore");
InProcSessionStore = (System.Web.SessionState.SessionStateStoreProviderBase)Activator.CreateInstance(inProcSessionStoreType);
InProcSessionStore.Initialize(null, null);
}
public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout) {
return InProcSessionStore.CreateNewStoreData(context, timeout);
}
public override void CreateUninitializedItem(HttpContext context, string id, int timeout) {
InProcSessionStore.CreateUninitializedItem(context, id, timeout);
}
public override void Dispose() {
InProcSessionStore.Dispose();
}
//... Implement the rest of the method in the same manner.
public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback) {
return InProcSessionStore.SetItemExpireCallback(expireCallback);
}
}
补充一下。
(编辑:我让它更通用一点)
首先,抽象包装的接口
interface ISessionStateItemCollectionWrapper : ISessionStateItemCollection
{
ISessionStateItemCollection WrappedCollection { get; set; }
}
因为我想在读取或写入会话项时进行记录,所以我为 ISessionStateItemCollection 添加了一个包装器
public class SessionStateItemCollectionWithInstrumentation : ISessionStateItemCollectionWrapper
{
public ISessionStateItemCollection WrappedCollection { get; set; }
//...
//...
//...
public object this[string name]
{
get
{
LogRead();
return _wrappedCollection[name];
}
set
{
LogWrite();
_wrappedCollection[name] = value;
}
}
//...
//More log on some methods
//...
}
然后,为了注入,我继承了SessionStateStoreData
class SessionStoreDataItemsInjector<T> : SessionStateStoreData where T:ISessionStateItemCollectionWrapper, new()
{
public SessionStoreDataItemsInjector(SessionStateStoreData wrappedData)
: base(new T()
{
WrappedCollection = wrappedData.Items
}, wrappedData.StaticObjects, wrappedData.Timeout)
{
}
}
然后我将它连接到 Don 提供的 class
abstract class InProcSessionStateInjected<T> : SessionStateStoreProviderBase where T : ISessionStateItemCollectionWrapper, new()
{
private SessionStateStoreProviderBase inProcSessionStore;
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
var inProcSessionStoreType = typeof(SessionStateStoreProviderBase).Assembly.GetType("System.Web.SessionState.InProcSessionStateStore");
inProcSessionStore = (SessionStateStoreProviderBase)Activator.CreateInstance(inProcSessionStoreType);
inProcSessionStore.Initialize(name, config);
}
public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
{
var sessionStateStoreData = inProcSessionStore.CreateNewStoreData(context, timeout);
return sessionStateStoreData.Items.GetType() != typeof(T) ? new SessionStoreDataItemsInjector<T>(sessionStateStoreData) : sessionStateStoreData;
}
public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
var sessionStateStoreData = inProcSessionStore.GetItem(context, id, out locked, out lockAge, out lockId, out actions);
if (sessionStateStoreData != null && sessionStateStoreData.Items.GetType() != typeof(T))
{
return new SessionStoreDataItemsInjector<T>(sessionStateStoreData);
}
return sessionStateStoreData;
}
public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
var sessionStateStoreData = inProcSessionStore.GetItemExclusive(context, id, out locked, out lockAge, out lockId, out actions);
if (sessionStateStoreData != null && sessionStateStoreData.Items.GetType() != typeof(T))
{
return new SessionStoreDataItemsInjector<T>(sessionStateStoreData);
}
return sessionStateStoreData;
}
在我正在开发的应用程序中,我们使用了 InProc ASP.NET SessionState 对象。
我想找到一种方法来在某些代码读取或写入 Session 对象时记录消息。
我知道 Item[] 索引,我想我应该以某种方式注入代码..或者继承 HttpSessionState class?
选项、想法、经验...?
您可以创建一个自定义的 SessionStateProvider,您可以从该提供程序中实例化 InProcSessionStateStore 的一个实例,并使用它来完成与会话存储处理相关的所有工作。
并且在这个自定义 SessionStateProvider 中,您可以执行所有的日志记录。
所以这是你必须做的:
创建一个新的class继承SessionStateStoreProviderBaseclass,假设它被命名为"MySessionStateProvider"
实现所有抽象 class 方法。
在 class 的构造函数中,使用反射创建 InProcSessionStateStore class 的实例(ASP.NET 使用它来存储会话状态当为 InProc 配置时 - 你的情况) 将此实例存储在变量中
- 在所有覆盖的方法中使用上述 InProc 实例 class 以执行必要的操作。
- 在 Web.Config 中配置此新提供程序
- 最后但同样重要的是,实施您的日志记录
这是示例代码(以及 link 其他人如何创建自定义提供程序的信息,如果您需要一个包含更多信息的工作示例)。
https://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstatestoreproviderbase(v=vs.110).aspx
http://www.codeproject.com/Articles/102000/ASP-NET-Custom-Session-Store-Provider-compatible-w
Web.Config
<sessionState mode="Custom" customProvider="custom_provider" ... >
<providers>
<add name="custom_provider" type="Xxxx.xxx.MySessionStateProvider"/>
</providers>
</sessionState>
MySessionStateProvider class 代码:
public class MySessionStateProvider : System.Web.SessionState.SessionStateStoreProviderBase {
private readonly SessionStateStoreProviderBase InProcSessionStore;
public MySessionStateProvider() {
var inProcSessionStoreType = typeof(System.Web.SessionState.SessionStateStoreProviderBase).Assembly.GetType("System.Web.SessionState.InProcSessionStateStore");
InProcSessionStore = (System.Web.SessionState.SessionStateStoreProviderBase)Activator.CreateInstance(inProcSessionStoreType);
InProcSessionStore.Initialize(null, null);
}
public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout) {
return InProcSessionStore.CreateNewStoreData(context, timeout);
}
public override void CreateUninitializedItem(HttpContext context, string id, int timeout) {
InProcSessionStore.CreateUninitializedItem(context, id, timeout);
}
public override void Dispose() {
InProcSessionStore.Dispose();
}
//... Implement the rest of the method in the same manner.
public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback) {
return InProcSessionStore.SetItemExpireCallback(expireCallback);
}
}
补充一下。
(编辑:我让它更通用一点)
首先,抽象包装的接口
interface ISessionStateItemCollectionWrapper : ISessionStateItemCollection
{
ISessionStateItemCollection WrappedCollection { get; set; }
}
因为我想在读取或写入会话项时进行记录,所以我为 ISessionStateItemCollection 添加了一个包装器
public class SessionStateItemCollectionWithInstrumentation : ISessionStateItemCollectionWrapper
{
public ISessionStateItemCollection WrappedCollection { get; set; }
//...
//...
//...
public object this[string name]
{
get
{
LogRead();
return _wrappedCollection[name];
}
set
{
LogWrite();
_wrappedCollection[name] = value;
}
}
//...
//More log on some methods
//...
}
然后,为了注入,我继承了SessionStateStoreData
class SessionStoreDataItemsInjector<T> : SessionStateStoreData where T:ISessionStateItemCollectionWrapper, new()
{
public SessionStoreDataItemsInjector(SessionStateStoreData wrappedData)
: base(new T()
{
WrappedCollection = wrappedData.Items
}, wrappedData.StaticObjects, wrappedData.Timeout)
{
}
}
然后我将它连接到 Don 提供的 class
abstract class InProcSessionStateInjected<T> : SessionStateStoreProviderBase where T : ISessionStateItemCollectionWrapper, new()
{
private SessionStateStoreProviderBase inProcSessionStore;
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
var inProcSessionStoreType = typeof(SessionStateStoreProviderBase).Assembly.GetType("System.Web.SessionState.InProcSessionStateStore");
inProcSessionStore = (SessionStateStoreProviderBase)Activator.CreateInstance(inProcSessionStoreType);
inProcSessionStore.Initialize(name, config);
}
public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
{
var sessionStateStoreData = inProcSessionStore.CreateNewStoreData(context, timeout);
return sessionStateStoreData.Items.GetType() != typeof(T) ? new SessionStoreDataItemsInjector<T>(sessionStateStoreData) : sessionStateStoreData;
}
public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
var sessionStateStoreData = inProcSessionStore.GetItem(context, id, out locked, out lockAge, out lockId, out actions);
if (sessionStateStoreData != null && sessionStateStoreData.Items.GetType() != typeof(T))
{
return new SessionStoreDataItemsInjector<T>(sessionStateStoreData);
}
return sessionStateStoreData;
}
public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
var sessionStateStoreData = inProcSessionStore.GetItemExclusive(context, id, out locked, out lockAge, out lockId, out actions);
if (sessionStateStoreData != null && sessionStateStoreData.Items.GetType() != typeof(T))
{
return new SessionStoreDataItemsInjector<T>(sessionStateStoreData);
}
return sessionStateStoreData;
}