Search code examples
ninject

Difference between .Resolve and .Get in Ninject


Just wanted to get some clarrification over the difference between Kernel.Resolve and Kernel.Get in ninject.

Description for Kernel.Get states

gets an instance of the specified service by using the first binding that matches the specified constraints

Description for Kernel.Resolve states

Resolves instances for the specified request. The instances are not actually resolved until a consumer iterates over the enumeration.

In which situations might you use either of these? (Right now I'm using Get exclusively)


Solution

  • Kernel.Get is an extension method (or a set of extension methods to be more precise) which live in ResolutionExtensions.cs.

    Kernel.Resolve is a method of IResolutionRoot.cs which is implemented by IKernel.

    Only by reading the description of the methods we can recon two things:

    1. ResolutionExtensions.Get<T>(this IResolutionRoot root) only returns the first match, which is resolved when the method is executed.

    2. IResolutionRoot.Resolve(IRequest request) returns an IEnumerable<T>, this enumerable will resolve each match only when enumerated, and there can be more than one match.


    Upon closer inspection, ResolutionExtensions.Get<T>(this IResolutionRoot root)'s implementation is:

    public static T Get<T>(this IResolutionRoot root, params IParameter[] parameters)
    {
        return GetResolutionIterator(root, typeof(T), null, parameters, false, true).Cast<T>().Single();
    }
    

    And GetResolutionIterator's implementation is

    private static IEnumerable<object> GetResolutionIterator(IResolutionRoot root, Type service, Func<IBindingMetadata, bool> constraint, IEnumerable<IParameter> parameters, bool isOptional, bool isUnique)
    {
        Ensure.ArgumentNotNull(root, "root");
        Ensure.ArgumentNotNull(service, "service");
        Ensure.ArgumentNotNull(parameters, "parameters");
    
        IRequest request = root.CreateRequest(service, constraint, parameters, isOptional, isUnique);
        return root.Resolve(request);
    }
    

    Which is essentially a wrapper method to IResolutionRoot.Resolve

    So ResolutionExtensions.Get<T>(this IResolutionRoot root) is enumerating IResolutionRoot.Resolve using Enumerable.Single.

    Conclusion

    Kernel.Get() == Kernel.Resolve().Single()