Skip to content

Instantly share code, notes, and snippets.

@dbuksbaum
Created April 26, 2015 01:38
Show Gist options
  • Save dbuksbaum/9d635366d98df0221c99 to your computer and use it in GitHub Desktop.
Save dbuksbaum/9d635366d98df0221c99 to your computer and use it in GitHub Desktop.
Type Tracking Extension for Unity
using System;
using Microsoft.Practices.Unity;
using System.Collections.Generic;
namespace Hazware.Commons.Unity
{
public class TypeTrackingExtension : UnityContainerExtension
{
#region Fields
private readonly Dictionary<Type, HashSet<string>> _registeredTypes = new Dictionary<Type, HashSet<string>>();
#endregion
#region Private Methods
protected override void Initialize()
{
Context.RegisteringInstance += OnNewInstance;
Context.Registering += OnNewType;
}
private void OnNewInstance(object sender, RegisterInstanceEventArgs e)
{
HashSet<string> names;
string name = string.IsNullOrEmpty(e.Name) ? string.Empty : e.Name;
if (!_registeredTypes.TryGetValue(e.RegisteredType, out names))
{ // not found, so add it
_registeredTypes.Add(e.RegisteredType, new HashSet<string> { name });
}
else
{ // already added type, so add name
names.Add(name);
}
}
private void OnNewType(object sender, RegisterEventArgs e)
{
HashSet<string> names;
string name = string.IsNullOrEmpty(e.Name) ? string.Empty : e.Name;
if (!_registeredTypes.TryGetValue(e.TypeFrom, out names))
{ // not found, so add it
_registeredTypes.Add(e.TypeFrom, new HashSet<string> { name });
}
else
{ // already added type, so add name
names.Add(name);
}
}
#endregion
#region CanResolve
/// <summary>
/// Determines whether this type can be resolved as the default.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>
/// <c>true</c> if this instance can resolve; otherwise, <c>false</c>.
/// </returns>
public bool CanResolve<T>()
{
return CanResolve<T>(null);
}
/// <summary>
/// Determines whether this type can be resolved with the specified name.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name">The name.</param>
/// <returns>
/// <c>true</c> if this instance can be resolved with the specified name; otherwise, <c>false</c>.
/// </returns>
public bool CanResolve<T>(string name)
{
HashSet<string> names;
if (_registeredTypes.TryGetValue(typeof(T), out names))
{
return names.Contains(name ?? string.Empty);
}
return false;
}
/// <summary>
/// Determines whether this instance can be resolved at all.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>
/// <c>true</c> if this instance can be resolved at all; otherwise, <c>false</c>.
/// </returns>
public bool CanResolveAny<T>()
{
return _registeredTypes.ContainsKey(typeof(T));
}
#endregion
#region TryResolve
/// <summary>
/// Tries to resolve the type, returning null if not found.
/// </summary>
/// <typeparam name="T">The type to try and resolve.</typeparam>
/// <returns>An object of type <see cref="T"/> if found, or <c>null</c> if not.</returns>
public T TryResolve<T>()
{
return TryResolve<T>(default(T));
}
/// <summary>
/// Tries to resolve the type with the specified of name, returning null if not found.
/// </summary>
/// <typeparam name="T">The type to try and resolve.</typeparam>
/// <param name="name">The name associated with the type.</param>
/// <returns>An object of type <see cref="T"/> if found, or <c>null</c> if not.</returns>
public T TryResolve<T>(string name)
{
return TryResolve<T>(name, default(T));
}
/// <summary>
/// Tries to resolve the type, returning null if not found.
/// </summary>
/// <typeparam name="T">The type to try and resolve.</typeparam>
/// <param name="defaultValue">The default value to return if type not found.</param>
/// <returns>An object of type <see cref="T"/> if found, or the <see cref="defaultValue"/> if not.</returns>
public T TryResolve<T>(T defaultValue)
{
if (!CanResolve<T>())
return defaultValue;
return Container.Resolve<T>();
}
/// <summary>
/// Tries to resolve the type with the specified of name, returning null if not found.
/// </summary>
/// <typeparam name="T">The type to try and resolve.</typeparam>
/// <param name="name">The name associated with the type.</param>
/// <param name="defaultValue">The default value to return if type not found.</param>
/// <returns>An object of type <see cref="T"/> if found, or the <see cref="defaultValue"/> if not.</returns>
public T TryResolve<T>(string name, T defaultValue)
{
if (!CanResolve<T>(name))
return defaultValue;
return Container.Resolve<T>(name);
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment