Closed rizi closed 2 years ago
"Injectables" are scoped, so you technically can have a value scoped to the root container, and then to each nested container. There is not formal fallback mechanism, and to be straightforward, that's a conscious design decision in Lamar to not support that kind of use case as it was extremely problematic to support in StructureMap.
You could fake this behavior by having a singleton holder type in the parent, then a scoped holder in a nested container. Use a Lambda registration to first check if the scoped handler is not null, then programmatically fall back to the parent. No change to Lamar is necessary to do that.
And also just to throw this out, I generally recommend against doing this kind of thing since it's going to confuse many devs and lead to subtle errors if you're not careful.
"Injectables" are scoped, so you technically can have a value scoped to the root container, and then to each nested container. There is not formal fallback mechanism, and to be straightforward, that's a conscious design decision in Lamar to not support that kind of use case as it was extremely problematic to support in StructureMap.
You could fake this behavior by having a singleton holder type in the parent, then a scoped holder in a nested container. Use a Lambda registration to first check if the scoped handler is not null, then programmatically fall back to the parent. No change to Lamar is necessary to do that.
And also just to throw this out, I generally recommend against doing this kind of thing since it's going to confuse many devs and lead to subtle errors if you're not careful.
@jeremydmiller Thx for the reply!
Could you provide a little bit more technical details. Do I have to mark the type as injectable? Or register it as singleton?
How do I check in the lambda instance if there is a needed container and how do I get access to the nested container?
Br
Something like this:
public class ParentHolder<T>
{
public T Tracked {get;set;
}
var container = Container.For(s => {
s.AddSingleton<ParentHolder<Foo>>(new ParentHolder<Foo>{Tracked = new Foo()});
// need this just to set up the injectable slot
s.Injectable<Foo>();
// And here's what I mean logically by the fall back. So Injectable<T> is scoped, ParentHolder<T> is at the root.
s.For<Foo>().Use(s => {
return s.GetInstance<Foo>() ?? s.GetInstance<ParentHolder<Foo>>().Tracked;
});
});
Something like this:
public class ParentHolder<T> { public T Tracked {get;set; } var container = Container.For(s => { s.AddSingleton<ParentHolder<Foo>>(new ParentHolder<Foo>{Tracked = new Foo()}); // need this just to set up the injectable slot s.Injectable<Foo>(); // And here's what I mean logically by the fall back. So Injectable<T> is scoped, ParentHolder<T> is at the root. s.For<Foo>().Use(s => { return s.GetInstance<Foo>() ?? s.GetInstance<ParentHolder<Foo>>().Tracked; }); });
Thank you very much!
Hi, I want to know if it's possible to register a type in the "root" container AND mark it as injectable.
My goal is that I have a default registration that is used for the root container and for nested containers and when I use nestedContainer.Inject(..........) it should overwrite the default registration for this specific nested container.
Is there a way to achieve this?
As soon as I mark a type as Injectable lamar always returns NULL (ignores the registration) as long as I don't use nestedContainer.Inject(.....)
Here is a small sample.