Closed jnm2 closed 3 years ago
Sounds great!
The way I would recommend this be implemented is that an Owned<T>
creates it's own scope, exactly like a Func<T>
, but unlike a Func<T>
the disposeAction is not stored for later, but given as one of the parameters to the Owned<T>
.
I think this should be fairly straightforward conceptually, but there'll be lots of places which will need changing in the code.
This enables classes to choose when and how many times to get a reference to a dependency and when to release a dependency while being perfectly agnostic about the lifespan of the dependency before and after this (singleton, transient, pooled, etc).
It also enables a class A to obtain dependency B which causes dependency C to be created. Dependency B knows about dependency C, but class A does not know about dependency C and cannot properly release or dispose it when it is finished using dependency B. Dependency B also can't assume that it owns and should dispose dependency C when it is itself disposed. The solution is to inject
Func<Owned<B>>
intoA
instead ofFunc<B>
.A comparable feature is Castle Windsor's Typed Factories feature where Windsor auto-implements any factory-like interface that you declare yourself and register as a typed factory. The
T IFactory<T>.Resolve()
call is logically equivalent toOwned<T> Func<Owned<T>>.Invoke()
and thevoid IFactory<T>.Release(T)
call is logically equivalent tovoid Owned<T>.Dispose()
.I don't really have an opinion on whether injecting bare
Owned<T>
should be supported, rather than injecting a delegate withOwned<T>
as the return type.