I have a situation where I have an object tree created by a special factory. This is somewhat similar to a DI container, but not quite.
Creation of objects always happens via constructor, and the objects are immutable.
Some parts of the object tree may not be needed in a given execution and should be created lazily. So the constructor argument should be something that is just a factory for on-demand creation. This looks like a job for Lazy
.
However, object creation may need to access slow resources and is thus always async. (The object factory's creation function returns a Task
.) This means that the creation function for the Lazy
would need to be async, and thus the injected type needs to be Lazy<Task<Foo>>
.
But I'd rather not have the double wrapping. I wonder if it is possible to force a Task
to be lazy, i.e. to create a Task
that is guaranteed to not execute until it is awaited. As I understand it, a Task.Run
or Task.Factory.StartNew
may start executing at any time (e.g. if a thread from the pool is idle), even if nothing is waiting for it.
public class SomePart
{
// Factory should create OtherPart immediately, but SlowPart
// creation should not run until and unless someone actually
// awaits the task.
public SomePart(OtherPart eagerPart, Task<SlowPart> lazyPart)
{
EagerPart = eagerPart;
LazyPart = lazyPart;
}
public OtherPart EagerPart {get;}
public Task<SlowPart> LazyPart {get;}
}