Skip to content

Instantly share code, notes, and snippets.

@JeffreyZhao
Created August 20, 2009 06:46
Show Gist options
  • Save JeffreyZhao/170879 to your computer and use it in GitHub Desktop.
Save JeffreyZhao/170879 to your computer and use it in GitHub Desktop.
Extensions
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class AttachDataAttribute : Attribute
{
public AttachDataAttribute(object key, object value)
{
this.Key = key;
this.Value = value;
}
public AttachDataAttribute() { }
public object Key { get; set; }
public object Value { get; set; }
}
public static class AttachDataExtensions
{
public static object GetAttachedData(this ICustomAttributeProvider provider, object key)
{
var attributes = (AttachDataAttribute[])provider.GetCustomAttributes(typeof(AttachDataAttribute), false);
return attributes.First(a => a.Key.Equals(key)).Value;
}
public static T GetAttachedData<T>(this ICustomAttributeProvider provider, object key)
{
return (T)provider.GetAttachedData(key);
}
public static object GetAttachedData(this Enum value, object key)
{
return value.GetType().GetField(value.ToString()).GetAttachedData(key);
}
public static T GetAttachedData<T>(this Enum value, object key)
{
return (T)value.GetAttachedData(key);
}
private static T CreateAttachedInstance<T>(ICustomAttributeProvider provider)
{
var type = typeof(T);
T t = (T)Activator.CreateInstance(type);
var attributes = (AttachDataAttribute[])provider.GetCustomAttributes(
typeof(AttachDataAttribute), false);
foreach (var attribute in attributes)
{
var property = type.GetProperty(attribute.Key.ToString(),
BindingFlags.SetField | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null)
{
property.SetValue(t, attribute.Value, null);
}
}
return t;
}
private static Dictionary<ICustomAttributeProvider, object> s_dictProviderInstanceMapping =
new Dictionary<ICustomAttributeProvider, object>();
private static object s_attachedInstanceMutex = new object();
public static T GetAttachedInstance<T>(this ICustomAttributeProvider provider)
{
if (!s_dictProviderInstanceMapping.ContainsKey(provider))
{
lock (s_attachedInstanceMutex)
{
if (!s_dictProviderInstanceMapping.ContainsKey(provider))
{
s_dictProviderInstanceMapping[provider] = CreateAttachedInstance<T>(provider);
}
}
}
return (T)s_dictProviderInstanceMapping[provider];
}
public static T GetAttachedInstance<T>(this Enum value)
{
return value.GetType().GetField(value.ToString()).GetAttachedInstance<T>();
}
}
public static class DictionaryExtensions
{
public static TDictionary CopyFrom<TDictionary, TKey, TValue>(this TDictionary source, IDictionary<TKey, TValue> copy)
where TDictionary : IDictionary<TKey, TValue>
{
foreach (var pair in copy)
{
source.Add(pair.Key, pair.Value);
}
return source;
}
public static TDictionary CopyFrom<TDictionary, TKey, TValue>(this TDictionary source, IDictionary<TKey, TValue> copy, IEnumerable<TKey> keys)
where TDictionary : IDictionary<TKey, TValue>
{
foreach (var key in keys)
{
source.Add(key, copy[key]);
}
return source;
}
public static TDictionary RemoveKeys<TDictionary, TKey, TValue>(this TDictionary source, IEnumerable<TKey> keys)
where TDictionary : IDictionary<TKey, TValue>
{
foreach (var key in keys)
{
source.Remove(key);
}
return source;
}
public static IDictionary<TKey, TValue> RemoveKeys<TKey, TValue>(this IDictionary<TKey, TValue> source, IEnumerable<TKey> keys)
{
foreach (var key in keys)
{
source.Remove(key);
}
return source;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment