我正在嘗試撰寫一個通用快取存盤庫,為正在快取的每個資料型別添加一個基本鍵。
public interface ICacheModel
{
private static readonly string _baseKey;
public static string GetBaseCacheKey()
{
return _baseKey;
}
}
public interface ICacheRepository<T> where T : class, ICacheModel
{
Task<T> GetAsync(string key);
}
public class CacheRepository<T> : ICacheRepository<T> where T : class, ICacheModel
{
private readonly IDistributedCache _distributedCache;
public CacheRepository(IDistributedCache distributedCache)
{
_distributedCache = distributedCache;
}
public async Task<T> GetAsync(string key)
{
var res = await _distributedCache.GetAsync<T>(T.GetBaseCacheKey() key );
return res;
}
}
然后我繼承我計劃從 ICacheModel 快取的任何物件,并在我需要在我的專案中快取的任何地方注入 ICacheRepository。
但GetBaseCacheKey()由于編譯器錯誤 CS0119,我無法訪問靜態方法
關于如何擁有此功能的任何想法?
更新:
public class CacheSampleClass : ICacheModel
{
public Guid Id { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
private static readonly string _baseKey = "CacheSampleClass-";
public static string GetBaseCacheKey()
{
return _baseKey;
}
}
這是我要快取的繼承類的示例。我希望 GetBaseCacheKey 在由 CacheSampleClass 制作的所有物件中是唯一的,并且與由繼承 ICacheModel 的其他類制作的所有物件不同
uj5u.com熱心網友回復:
不能實作靜態介面方法;靜態成員只屬于它們的宣告型別。
你可以這樣做:
public interface ICacheModelKeyProvider<T> where T : class
{
string BaseKey { get; }
}
然后在您的存盤庫中:
public class CacheRepository<T> : ICacheRepository<T> where T : class
{
private readonly IDistributedCache distributedCache;
private readonly ICacheModelKeyProvider<T> keyProvider;
public CacheRepository(
IDistributedCache distributedCache,
ICacheModelKeyProvider<T> keyProvider)
{
this.distributedCache = distributedCache;
this.keyProvider = keyProvider;
}
public async Task<T> GetAsync(string key)
{
var res = await _distributedCache.GetAsync<T>(keyProvider.BaseKey key);
return res;
}
}
然后,您創建的每個模型型別都需要一個,ICacheModelKeyProvider然后才能擁有存盤庫。
例如
public class CacheSampleClass
{
public Guid Id { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
public class CacheSampleClassKeyProvider : ICacheModelKeyProvider<CacheSampleClass>
{
public string BaseKey { get; } = "CacheSampleClass-";
}
或者,如果您想要默認行為,您甚至可以擁有一個通用提供程式:
public class DefaultKeyProvider<T> : ICacheModelKeyProvider<T>
{
public string BaseKey { get; } = $"{typeof(T).Name}-";
}
如果感覺更整潔,您甚至可以嵌套該類:
public class CacheSampleClass
{
public Guid Id { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public class KeyProvider : DefaultKeyProvider<CacheSampleClass> { }
}
uj5u.com熱心網友回復:
最簡單的解決方案可能是使用反射來獲取類名作為“baseCacheKey”。
_distributedCache.GetAsync<T>(typeof(T).FullName key );
另一種解決方案是將基本鍵定義為快取物件的引數,而不是型別:
public CacheRepository(IDistributedCache distributedCache, string baseKey)
...
第三種解決方案是在介面中定義一個屬性:
public interface ICacheModel
{
public string BaseKey {get;}
}
所述介面的實作可以只提供回傳常量或文字值的 get 方法的實作,因此沒有任何針對每個物件的欄位。但是該屬性不能像發布的示例中那樣是靜態的。
每種選擇都有一些優點和缺點,因此這取決于您想要做什么。
uj5u.com熱心網友回復:
介面中的靜態成員是在 C# 8.0 中引入的,我建議您避免使用它們,因為介面通常應該將實作(欄位)與合同(方法或屬性)斷開連接。
在您的情況下,最好轉換為常規財產
public interface ICacheModel
{
string GetBaseCacheKey();
}
并將使用靜態欄位的實作移動到實作您的介面的類
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/363421.html
標籤:C# 泛型 堆栈交换.redis
