【问题标题】:inject - InSessionScope Extension problems with AppFabric Cache注入 - AppFabric 缓存的 InSessionScope 扩展问题
【发布时间】:2015-02-25 09:17:50
【问题描述】:

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 总是创建一个新的对象,而 SessionScope 不再起作用。

编辑1:

我们正在使用此功能

https://msdn.microsoft.com/en-us/library/hh361711%28v=azure.10%29.aspx

在这里我可以使用标准的“HttpContext.Current.Session”对象,列表内容存储在服务器上而不是本地机器上。

【问题讨论】:

  • 可以添加app fabric的代码吗?
  • AppFabric 没有代码 - 它只是 web.config 中的一个设置,然后所有 SessionData 都存储在服务器上,而不再存储在本地计算机上。我需要以某种方式重写 InSessionScope 扩展,但我不知道如何
  • 这正是我的问题,您的扩展程序中的代码是什么。因为无论您在 web.config 中连接什么,HttpContext.Current 都不会返回 AppFabric 缓存。无论如何,您拥有哪个版本的 AppFabric? (1.0 或 1.1)
  • AppFabric 缓存版本 1.1
  • 你添加的链接没有说可以使用'HttpContext.Current.Session'?

标签: c# asp.net-mvc ninject ninject.web.mvc ninject-extensions


【解决方案1】:

因此,在架构上,您需要将 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;
}

【讨论】:

  • App Fabric 缓存在我上面的实现中就像一个魅力,这不是问题所在。我们的问题是 Ninject InSessionScope 不适用于 AppFabric 缓存,因为 ninjects 使用本地引用,当我使用 AppFabric 缓存时,不再有本地引用,我总是从 ninject 获得一个新对象
  • 嗯,appfabric 不会给你一个本地引用,每个对象每次都被反序列化。例如。你不能那样使用它。
【解决方案2】:

我找到了一个“解决方案”,到目前为止它并不完美,因为我避免使用带有 Localstore 的 AppFabric Store 作为对象引用。

    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];
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多