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

Posted on


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<T>, but quickly ran into an issue — I also require an IObjectSet<TEntity> 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<IObjectSet<TEntity>>(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<T, TResult> where TResult : class {
        private readonly Lazy<T> _dependency;
        private readonly MethodInfo _factory;

        public LazyFactory(Lazy<T> lazyDependency, MethodInfo lazyFactory) {
            // Argument null checks omitted for brevity
            Contract.Requires(lazyFactory.GetParameters().Count() == 0);

            _factory = lazyFactory;
            _dependency = lazyDependency;

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

    public static Func<TOut> GetLazyFactory<TIn, TOut>(
        Lazy<TIn> dependency, MethodInfo factoryInfo) where TOut : class {
        return new LazyFactory<TIn, TOut>(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<IObjectContext, IObjectSet<TEntity>>(
    new Lazy<IObjectContext>(factory.Create), 
    typeof (IObjectContext).GetMethod("ObjectSet"));

var lazyObjectSet = new Lazy<IObjectSet<TEntity>>(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:


The problem is that my IObjectContext.ObjectSet() method has the generic return type IObjectSet<TEntity>, 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<TOut> GetLazyFactory<TIn, TOut>(Lazy<TIn> dependency, string factoryName)
    where TOut : class
    Type outT = typeof(TOut);       // Expected return type of factory method
    MethodInfo factoryMethodInfo =  // Should return TOut

        // 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<TIn, TOut>(dependency, factoryMethodInfo).Invoke;

Leave a Reply

Your email address will not be published. Required fields are marked *