Edit: Source code posted to Hazware Unity Extensions on GitHub
My personal inversion of control container is Unity. However, I occasionally find myself looking for functionality from the other .NET IoC containers I have used, such as Ninject and Castle Windsor. Here is the code that came out from trying to solve this need.
I was working on some Unit of Work code for NHibernate and I found the need to query the container to check if a type was registered. I checked the Unity documentation for the IUnityContainer.Resolve<>() method, and as usual, the documentation always seems to be missing the piece of information I need. It did not describe the result of calling the container for a type that is not registered. Having used Unity for a while now, I was pretty sure it through an exception, but just be sure, I wrote a quick test.
[Test] public void TestUnity() { IoC.Container.Resolve<IDisposable>(); }
And result:
Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "System.IDisposable", name = "". Exception message is: The current build operation (build key Build Key[System.IDisposable, null]) failed: The current type, System.IDisposable, is an interface and cannot be constructed. Are you missing a type mapping?
I could not find another way to check for type registration, so off to Google I went. One discussion from the Unity discussion group seemed to cover this program [see: IsInstanceRegistered?]. This seemed to be the answer, until I compared against my unit tests to validate my usage. The solution provided does not provide for checked for default or named registered types. The problem is that Unity has a keyed resolver in that it either returns a default registration that is unnamed, or a specifically named registration. Thus, it is possible for this check to return true, but for the Resolve call to fail. I wanted something more in line with Unity’s usage model.
I did find one other posted solution. That solution recommend just doing a ResolveAll and returning true if the collection was not empty. However, this is highly inefficient. It forces resolution of the types, triggering instantiation, even if not needed.
Given these limitations, I decided to write my own solution. I like the idea of doing it as a Unity extension, so I retained that model. So here is my code for solution.
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 }
Source Code TypeTrackingExtension.cs

[...] and it returns null if it can’t. This solution was provided by David Buksbaum in his blog post Type Tracking Extension for Unity. This extension is added to the container in this wrapper’s [...]
[...] code sharing site to post my open source code to – GitHub. I posted all of the source code for my Type Tracking Unity Extension there, and decided to follow the Ninject model for licensing – I dual licensed it as MS-PL and [...]
Hi,
how I use TypeTrackingExtension ? sample code,please !!!
thanks
Hi espinete. I will post up an example a little later today.
Hi espinete. See the new post Extending and Demonstrating the Type Tracking Extension for Unity. I hope this helps.
[...] I have received a few requests for some changes and an example for my Type Tracking Extension for Unity. This post is to address those requests. Of course, all of the source code for this post is added [...]
[...] few years ago I wrote Type Tracking Extension for Unity and Extending and Demonstrating the Type Tracking Extension for Unity, and while I have been using [...]