[英]storing and accessing implementation specific data of a class from generic type of its interface in c#
我正在嘗試編寫一個通用緩存存儲庫,為正在緩存的每個數據類型添加一個基本鍵。
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。
但由於編譯器錯誤 CS0119,我無法訪問靜態方法GetBaseCacheKey()
關於如何擁有此功能的任何想法?
更新:
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 的其他類制作的所有對象不同
最簡單的解決方案可能是使用反射來獲取類名作為“baseCacheKey”。
_distributedCache.GetAsync<T>(typeof(T).FullName + key );
另一種解決方案是將基本鍵定義為緩存對象的參數,而不是類型:
public CacheRepository(IDistributedCache distributedCache, string baseKey)
...
第三種解決方案是在接口中定義一個屬性:
public interface ICacheModel
{
public string BaseKey {get;}
}
所述接口的實現可以只提供返回常量或文字值的 get 方法的實現,因此沒有任何針對每個對象的字段。 但是該屬性不能像發布的示例中那樣是靜態的。
每種選擇都有一些優點和缺點,因此這取決於您想要做什么。
接口中的靜態成員是在 C# 8.0 中引入的,我建議您避免使用它們,因為接口通常應該將實現(字段)與合同(方法或屬性)斷開連接。
在您的情況下,最好轉換為常規財產
public interface ICacheModel
{
string GetBaseCacheKey();
}
並將使用靜態字段的實現移動到實現您的接口的類
不能實現靜態接口方法; 靜態成員只屬於它們的聲明類型。
你可以這樣做:
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> { }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.