Providing factory method to Lazy when factory exists on another lazy instance? The Problem

I found myself needing an instance of an IObjectContext interface that should never be null, but wanting to delay instantiation until after some required resources have been loaded.

I decided to approach this with Lazy&lt;T&gt;, but quickly ran into an issue -- I also require an IObjectSet&lt;TEntity&gt; that is never null and lazy instantiated. The problem is this:

// lazyObjectSet needs to be created directly after lazyContext, but I need to 
// delay instantiating both. The desired factory method exists on lazyContext,
// but accessing lazyContext.Value instantiates context before it is needed:
//
var lazyObjectSet = new Lazy&lt;IObjectSet&lt;TEntity&gt;&gt;(lazyContext.Value.FactoryMethodName);




My Solution

I would like suggestions for improvements on my approach, or alternative approaches to the problem.

public static class LazyExtensions {
    private class LazyFactory&lt;T, TResult&gt; where TResult : class {
        private readonly Lazy&lt;T&gt; _dependency;
        private readonly MethodInfo _factory;

        public LazyFactory(Lazy&lt;T&gt; lazyDependency, MethodInfo lazyFactory) {
            // Argument null checks omitted for brevity
            Contract.Requires(typeof(TResult).Equals(lazyFactory.ReturnType));
            Contract.Requires(lazyFactory.GetParameters().Count() == 0);

            _factory = lazyFactory;
            _dependency = lazyDependency;
        }

        public TResult Invoke() {
            return (TResult) _factory.Invoke(_dependency.Value, null);
        }
    }

    public static Func&lt;TOut&gt; GetLazyFactory&lt;TIn, TOut&gt;(
        Lazy&lt;TIn&gt; dependency, MethodInfo factoryInfo) where TOut : class {
        return new LazyFactory&lt;TIn, TOut&gt;(dependency, factoryInfo).Invoke;
    }
}


Now I can use GetLazyFactory() to write the following, and the context should not be instantiated until lazyObjectSet.Value is accessed:

var lazyFactory = LazyExtensions.GetLazyFactory&lt;IObjectContext, IObjectSet&lt;TEntity&gt;&gt;(
    new Lazy&lt;IObjectContext&gt;(factory.Create), 
    typeof (IObjectContext).GetMethod("ObjectSet"));

var lazyObjectSet = new Lazy&lt;IObjectSet&lt;TEntity&gt;&gt;(lazyFactory);


How can this be improved, and is there a better way of doing this?
In conjunction with the rest of the code, the following line exhibits a bug:

Contract.Requires(typeof(TResult).Equals(lazyFactory.ReturnType));


The problem is that my IObjectContext.ObjectSet() method has the generic return type IObjectSet&lt;TEntity&gt;, and lazyFactory doesn't have type information for TEntity.

Specifically, the type parameter for lazyFactory is unknown because it's obtained using GetMethod(). As a result, Equals() returns false and the constraint fails with an exception. 

I solved the problem by modifying GetLazyFactory to accept a method name string and obtain the MethodInfo itself, calling MakeGenericMethod() as necessary.

public static Func&lt;TOut&gt; GetLazyFactory&lt;TIn, TOut&gt;(Lazy&lt;TIn&gt; dependency, string factoryName)
    where TOut : class
{
    Type outT = typeof(TOut);       // Expected return type of factory method
    MethodInfo factoryMethodInfo =  // Should return TOut
        typeof(TIn).GetMethod(factoryName); 

    if(outT.IsGenericType)
    {
        // Get generic type argument of TOut, making sure exactly 1 exists.
        Type tParam = outT.GetSingleGenericArgument(); 

        // We must specify the generic type or Type.Equals() will yield false.
        factoryMethodInfo = factoryMethodInfo.MakeGenericMethod(tParam);
    }
    return new LazyFactory&lt;TIn, TOut&gt;(dependency, factoryMethodInfo).Invoke;
}