Hey Frank,
That's exactly what we have done;this is what I have in my current project (perhaps could be cleaner, code is old):
public class SingletonConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (!type.IsConcrete() || !type.CanBeCreated())
return;
if (!type.HasAttribute<SingletonAttribute>()) // Simple extension method to reflect the attributes
return;
var interfaceName = GetDefaultInterfaceName(type);
var interfaceType = type.GetInterface(interfaceName);
if (interfaceType == null)
return;
registry.For(interfaceType).Singleton().Use(type);
}
private string GetDefaultInterfaceName(Type type)
{
return string.Format("I{0}", type.Name);
}
}
As for the attribute itself (Warning: scary code ahead!):
public class SingletonAttribute : Attribute
{
}
And the extension methods:
/// <summary>
/// Indicates whether the given type has any attribute of the specified attribute type.
/// </summary>
/// <typeparam name="TAttribute">The type of the attribute.</typeparam>
/// <param name="value">The object instance to check.</param>
/// <returns>A boolean indicating whether <paramref name="value"/> contains any attribute of type <typeparamref name="TAttribute"/></returns>
public static bool HasAttribute<TAttribute>(this Type value) where TAttribute : Attribute
{
return value.GetAttributes<TAttribute>().Any();
}
/// <summary>
/// Determines whether an instance implements the specified interface.
/// </summary>
/// <typeparam name="TInterface">The interface that has to be implemented by <paramref name="type"/></typeparam>
/// <param name="type">The type that has to implement <typeparamref name="TInterface"/></param>
/// <returns>A boolean indicating whether <paramref name="type"/> implements <typeparamref name="TInterface"/>.</returns>
public static bool Implements<TInterface>(this Type type)
{
return typeof(TInterface).IsAssignableFrom(type);
}
/// <summary>
/// Returns a sequence of attributes for the given type.
/// </summary>
/// <typeparam name="TAttribute">The type of the attribute.</typeparam>
/// <param name="value"></param>
/// <returns></returns>
private static IEnumerable<TAttribute> GetAttributes<TAttribute>(this Type value) where TAttribute : Attribute
{
var attributes = value.GetCustomAttributes(true);
return attributes.Length == 0 ? Enumerable.Empty<TAttribute>() : attributes.Cast<Attribute>().OfType<TAttribute>();
}