Closed YairHalberstadt closed 3 years ago
@jnm2 pull the latest master - should hopefully fix the issue.
@YairHalberstadt I think I'm back to implementing the actual change when I get a chance to come back to this. Should I start a PR for some/all of the commits before the last one to keep it separate?
Whatever's easiest for you - I'm ok reviewing them altogether or separately
So this is what I'm going to try to do next.
-disposeActions_func_0_1 = new global::System.Collections.Concurrent.ConcurrentBag<global::System.Action>();
func_0_1 = () =>
{
global::C c_1_2;
global::B b_1_1;
global::StrongInject.Owned<global::B> owned_1_0;
c_1_2 = new global::C();
try
{
b_1_1 = new global::B(c: c_1_2);
try
{
- owned_1_0 = new global::StrongInject.Owned<global::B>(b_1_1, );
+ owned_1_0 = new global::StrongInject.Owned<global::B>(b_1_1, () =>
+ {
+ ((global::System.IDisposable)b_1_1).Dispose();
+ ((global::System.IDisposable)c_1_2).Dispose();
+ });
}
catch
{
((global::System.IDisposable)b_1_1).Dispose();
throw;
}
}
catch
{
((global::System.IDisposable)c_1_2).Dispose();
throw;
}
- disposeActions_func_0_1.Add(() =>
- {
- ((global::System.IDisposable)b_1_1).Dispose();
- ((global::System.IDisposable)c_1_2).Dispose();
- });
return owned_1_0;
};
This is for:
using System;
using StrongInject;
[Register(typeof(A))]
[Register(typeof(B))]
[Register(typeof(C))]
public partial class Container : IContainer<A>
{
}
public record A(Func<Owned<B>> b);
public record B(C c) : IDisposable { public void Dispose() { } }
public record C : IDisposable { public void Dispose() { } };
@YairHalberstadt Deciding not to dispose Owned<T>
instances after the requesting component's Dispose/Async method completes means that we won't have a way to clean up Owned<T>
instances if the requesting component throws in the constructor after invoking the func:
try
{
a_0_0 = new global::A(b: func_0_1);
}
catch
{
// This can't free any Owned<T> instances that `A..ctor` caused to exist before it threw an exception,
// because we don't dispose Owned<T> in disposeActions_func_0_1.
foreach (var disposeAction in disposeActions_func_0_1)
disposeAction();
throw;
}
Think I'm possibly done, just need to write a ton of tests and maybe find interactions that don't work.
global::System.Func<global::StrongInject.Owned<global::B>> func_0_1;
global::A a_0_0;
func_0_1 = () =>
{
global::C c_1_1;
global::B b_1_0;
global::StrongInject.Owned<global::B> owned_1_0;
c_1_1 = new global::C();
try
{
b_1_0 = new global::B(c: c_1_1);
}
catch
{
((global::System.IDisposable)c_1_1).Dispose();
throw;
}
owned_1_0 = new global::StrongInject.Owned<global::B>(b_1_0, () =>
{
((global::System.IDisposable)b_1_0).Dispose();
((global::System.IDisposable)c_1_1).Dispose();
});
return owned_1_0;
};
a_0_0 = new global::A(b: func_0_1);
Deciding not to dispose Owned
instances after the requesting component's Dispose/Async method completes means that we won't have a way to clean up Owned instances if the requesting component throws in the constructor after invoking the func
I don't think that's a problem. The moment I pass you an Owned, you're responsible for disposing it. If I pass you a Func<Owned>
then if the Func
throws, I will clear up, but if it returns, you are responsible for disposing the Owned
even if you throw in the same method, and even if that method is called as part of dependency resolution.
I think I'm finished the implementation except for investigating deduplicating of local functions when Owned of a given type is used more than once, including everything we've discussed so far. I'll also need to see if there are any more corner cases worth testing, including ones that should possibly get diagnostics, and also write tests of the behavior of the generated code.
Here's the code to compare to the local functions sample you created (https://github.com/YairHalberstadt/stronginject/pull/143#discussion_r687037505):
can you pull from main please to fix the tests? Thanks
Yep, the diff should look a lot cleaner now! Hopefully I'll get to the remaining comments soon.
Silly thing, can I start a new PR as the author so I can find it more easily in the future? I was very confused here for three minutes.
Of course, go for it
Looks like I can't create a PR as long as this one is open without using a new branch name. Oh well.
@YairHalberstadt Do you want to either link this to https://github.com/YairHalberstadt/stronginject/issues/140 or close the PR and let me set one up and write the PR title and link it?
Closing so you can open a new PR
@YairHalberstadt Cool, https://github.com/YairHalberstadt/stronginject/pull/149 is set up and ready to continue.
@YairHalberstadt I get this email from my fork repo on every push. Any idea how to disable TOC generator in my fork?