gpt4 book ai didi

c# - ASP.NET Core 2.x 中间件的自定义依赖注入(inject)解析器?

转载 作者:行者123 更新时间:2023-11-30 15:15:23 24 4
gpt4 key购买 nike

给定一个 ASP.NET Core 2.x 应用程序,假设我正在使用两种分布式缓存机制:

services.AddDistributedSqlServerCache()
services.AddDistributedRedisCache()

据我了解,由于 Redis 是最后注册的,因此只要请求 IDistributedCache 实例,它就会解析为 RedisCache 实现。

在我的项目中,我还使用了 Distributed-Cache 标签助手,我想将其解析为 RedisCache(没问题,适用于上述设置)。

不过,我也在使用 Session 中间件,它也需要一个 IDistributedCache 实现。

我需要 Session 中间件来解析 SQL 分布式缓存和 Distributed-Cache 标签助手以及对 IDistributedCache 的任何其他请求> 缓存以解析为 RedisCache

如果我明白this文章正确,您可以指定服务定位器解析到哪个实现以对 services.AddSingleton 进行通用调用,但这似乎并没有转换像 AddSession() 这样的中间件注册辅助函数>.

有什么解决办法吗?

最佳答案

AddDistributedSqlServerCache()AddDistributedRedisCache() 都为 IDistributedCache 注册了一个单例:SqlServerCache RedisCache 分别。由于依赖组件仅依赖于 IDistributedCache,因此它们都将获得相同的分布式缓存实现(取决于最后注册的内容)。

这通常是设计使然,因为实现,例如 session 中间件,不应该关心 IDistributedCache 的实际注册实现是什么。这仅取决于是否存在一些并使用它。同样,其他服务也将只使用一个分布式缓存依赖项。

通常,没有办法解决这个问题。您最终可以做的是创建一些实现 IDistributedCache 本身的适配器,然后根据传递的参数委托(delegate)给 SQL Server 缓存或 Redis 缓存。

对于您的情况,有一种更简单的方法。由于 ASP.NET Core 的构建具有很强的可扩展性,并且大多数组件可以被其他实现简单地交换,我们可以在这里利用它来使 session 中间件只使用专门的分布式缓存,而其他一切都回退到默认缓存。

为此,我们只需实现 ISessionStore 并注册它,这基本上也是 AddSession() 所做的。在自定义 session 存储实现中,我们不依赖于 IDistributedCache,而是直接依赖于 SqlServerCache。这样一来,我们就不会回退到默认的 IDistributedCache(无论那是什么),而是强制系统使用 SqlServerCache

public class SqlServerCacheSessionStore : ISessionStore
{
private readonly IDistributedCache _cache;
private readonly ILoggerFactory _loggerFactory;

public SqlServerCacheSessionStore(SqlServerCache cache, ILoggerFactory loggerFactory)
{
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
}

public ISession Create(string sessionKey, TimeSpan idleTimeout, TimeSpan ioTimeout, Func<bool> tryEstablishSession, bool isNewSessionKey)
{
if (string.IsNullOrEmpty(sessionKey))
throw new ArgumentNullException(nameof(sessionKey));
if (tryEstablishSession == null)
throw new ArgumentNullException(nameof(tryEstablishSession));

return new DistributedSession(_cache, sessionKey, idleTimeout, ioTimeout, tryEstablishSession, _loggerFactory, isNewSessionKey);
}
}

这实际上与 DistributedSessionStore 的实现相同,它是默认的 ISessionStore 实现,只是我们依赖于 SqlServerCache 而不是 IDistributedCache.

现在,我们只需要在 Configure 方法中连接所有内容:

// we keep the Redis cache as the default
services.AddDistributedRedisCache();

// no call to `AddSqlServerCache` as we don’t want to overwrite the `IDistributedCache`
// registration; instead, register (and configure) the SqlServerCache directly
services.AddSingleton<SqlServerCache>();
services.Configure<SqlServerCacheOptions>(options =>
{
// here goes the configuration that would normally be done in the
// configure action passed to `AddSqlServerCache`
options.ConnectionString = Configuration.GetConnectionString("DistributedCache");
});

// add session, but overwrite the `ISessionStore` afterwards
services.AddSession();
services.AddTransient<ISessionStore, SqlServerCacheSessionStore>();

这应该就是全部了。因此,当 session 中间件现在解析 ISessionStore 时,它将获得 SqlServerCacheSessionStore,它直接依赖于 SqlServerCache 而不是一般的 IDistributedCache 这将是 Redis 缓存。

关于c# - ASP.NET Core 2.x 中间件的自定义依赖注入(inject)解析器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52067152/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com