我一直在玩弄自定義屬性今天晚上,看看我是否可以簡化我的緩存層。我想出了以下內容:這是在方法和類上創建和使用自定義屬性的正確方法嗎?
namespace AttributeCreationTest
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)]
public class Cache : Attribute
{
public Cache()
{
Length = "01h:30m";
}
public string Length;
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class CacheIdentifier : Attribute
{
}
[Cache]
class Class1
{
[CacheIdentifier]
public int ID { get; set; }
}
class Class2
{
[CacheIdentifier]
public bool ID { get; set; }
}
[Cache(Length = "01h:10m")]
class Class3
{
[CacheIdentifier]
public string ID { get; set; }
}
class Program
{
static void Main(string[] args)
{
var f1 = new Class1 { ID = 2 };
var f2 = new Class2 { ID = false };
var f3 = new Class3 { ID = "someID" };
DoCache(f1);
DoCache(f2);
DoCache(f3);
}
public static void DoCache(object objectToCache)
{
var t = objectToCache.GetType();
var attr = Attribute.GetCustomAttribute(t, typeof(Cache));
if (attr == null) return;
var a = (Cache)attr;
TimeSpan span;
if (TimeSpan.TryParse(a.Length.Replace("m", "").Replace("h", ""), out span))
{
Console.WriteLine("name: {0}, {1}", t.Name, span);
ExtractCacheData(objectToCache);
return;
}
throw new Exception(string.Format("The Length value of {0} for the class {1} is invalid.", a.Length, t.Name));
}
public static void ExtractCacheData(object o)
{
var t = o.GetType();
foreach (var prop in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (Attribute.IsDefined(prop, typeof(CacheIdentifier)))
{
Console.WriteLine(" type: {0}, value {1}", prop.PropertyType, prop.GetValue(o));
break;
}
throw new Exception(string.Format("A CacheIdentifier attribute has not been defined for {0}.", t.Name));
}
}
}
}
「緩存」屬性將被充實,但我把它最小,同時學習C#這個區域。我的想法是允許更容易緩存項目,包括指定緩存對象的時間量的簡化方法。
這看起來好嗎?使用這種模式將項目緩存到緩存中會有什麼顯着的性能命中嗎?
我一直無法找到任何詳細的涵蓋這種想法的任何教程,所以任何建議,將不勝感激。
謝謝llya!我以前從未遇到過PostSharp,但我一定會查看它。我考慮使用一個接口,但我接管的項目遵循DDD,我不確定其他程序員會過分熱衷於向域對象(要緩存的類)添加非域特定信息 - 這是我儘管如此! –
@ChrisW是的,但屬性也是一個依賴項,也是一個非域特定的信息。這就是爲什麼羅伯特馬丁批評依賴注入的屬性如「注入」。 –
這是非常真實的 - 就在我發佈它後,打我,但你回答之前,我設法編輯我的帖子:)。我會與其他開發人員討論使用哪種方法 - 無論選擇哪種方法,最好在屬性創建時使用此背景。 –