Ninject没有为网站提供InSessionScope绑定,因此我们创建了自己的扩展:
public static IBindingNamedWithOrOnSyntax<T> InSessionScope<T>(this IBindingInSyntax<T> parent)
{
return parent.InScope(SessionScopeCallback);
}
private const string _sessionKey = "Ninject Session Scope Sync Root";
private static object SessionScopeCallback(IContext context)
{
if (HttpContext.Current.Session[_sessionKey] == null)
{
HttpContext.Current.Session[_sessionKey] = new object();
}
return HttpContext.Current.Session[_sessionKey];
}
此扩展程序正常工作,直到我们使用标准的本地SessionStore。
但是我们改变了SessionStore,现在我们使用“AppFabricCacheSessionStoreProvider”,这个商店不再是服务器上的本地机器了。
问题是Ninject试图解析一个被序列化和反序列化的对象的引用,它来自服务器而不是来自本地内存,所以ninject无法找到引用。结果是,ninjects始终创建一个新的Object,SessionScope不再起作用。
编辑1:
我们正在使用此功能
https://msdn.microsoft.com/en-us/library/hh361711%28v=azure.10%29.aspx
在这里我可以使用标准的“HttpContext.Current.Session”对象,列表内容存储在服务器上而不是本地机器上。
答案 0 :(得分:0)
所以在架构上你有一个问题,你需要在某处存储AppFabric的设置,这是你的静态方法的问题。但假设您创建了一个公共静态类,如下所示:
public static class AppCache
{
public static DataCache Cache { get; private set; }
static AppCache()
{
List<DataCacheServerEndpoint> servers = new List<DataCacheServerEndpoint>(1);
servers.Add(new DataCacheServerEndpoint("ServerName", 22233)); //22233 is the default port
DataCacheFactoryConfiguration configuration = new DataCacheFactoryConfiguration
{
Servers = servers,
LocalCacheProperties = new DataCacheLocalCacheProperties(),
SecurityProperties = new DataCacheSecurity(),
RequestTimeout = new TimeSpan(0, 0, 300),
MaxConnectionsToServer = 10,
ChannelOpenTimeout = new TimeSpan(0, 0, 300),
TransportProperties = new DataCacheTransportProperties() { MaxBufferSize = int.MaxValue, MaxBufferPoolSize = long.MaxValue }
};
DataCacheClientLogManager.ChangeLogLevel(System.Diagnostics.TraceLevel.Off);
var _factory = new DataCacheFactory(configuration);
Cache = _factory.GetCache("MyCache");
}
}
然后您可以像这样更改扩展名:
public static IBindingNamedWithOrOnSyntax<T> InSessionScope<T>(this IBindingInSyntax<T> parent)
{
return parent.InScope(SessionScopeCallback);
}
private const string _sessionKey = "Ninject Session Scope Sync Root";
private static object SessionScopeCallback(IContext context)
{
var cachedItem = AppCache.Cache.Get("MyItem"); // IMPORTANT: For concurrency reason, get the whole item down to method scope.
if (cachedItem == null)
{
cachedItem = new object();
AppCache.Cache.Put("MyItem", cachedItem);
}
return cachedItem;
}
答案 1 :(得分:0)
我找到了一个&#34;解决方案&#34;到目前为止它的工作并不完美,因为我正在避免AppFabric商店使用Localstore作为对象参考。
public static IBindingNamedWithOrOnSyntax<T> InSessionScope<T>(this IBindingInSyntax<T> parent)
{
return parent.InScope(SessionScopeCallback);
}
public static Dictionary<string, object> LocalSessionStore = new Dictionary<string, object>();
private const string _sessionKey = "Ninject Session Scope Sync Root";
private static object SessionScopeCallback(IContext context)
{
var obj = new object();
var key = (string)HttpContext.Current.Session[_sessionKey];
if (string.IsNullOrEmpty(key))
{
var guid = Guid.NewGuid().ToString();
HttpContext.Current.Session[_sessionKey] = guid;
LocalSessionStore.Add(guid, obj);
}
else if(!LocalSessionStore.ContainsKey(key))
{
LocalSessionStore.Add(key, obj);
return LocalSessionStore[key];
}
else if (LocalSessionStore.ContainsKey(key))
{
return LocalSessionStore[key];
}
return HttpContext.Current.Session[_sessionKey];
}
}