Closed stanmots closed 6 years ago
Hello.
Yes you can make more DIContainers - DIPart allows you to do this without duplicating code.
But weakSingle
will live while there are references to the object. In your example if you destroy VC1, VC2, VC3 then is removed object.
Or you can use objectGraph
, but it will only fit if all VC are generated together.
I think in your case probably it is better to use weakSingle
.
Thanks for the reply,
But, suppose we have configured a global container
let globalContainer = DIContainer()
and a container as per my use case
let useCaseContainer = DIContainer()
Now to inject dependencies and present a view controller we must create an appropriate storyboard:
let storyboard = DIStoryboard.create(name: "Main", bundle: nil, container: container)
Here is the dilemma: what container should we pass to the storyboard factory method? What if we need the singleton objects from globalContainer
to be available in useCaseContainer
?
I see that DIPart
helps in reducing code duplications. However, if understand it correctly, each container will create its own instances of the objects which were configured as singles. So, is there a way to share these instances between containers?
You can do this:
class Part: DIPart {
static func load(container: DIContainer) {
container.registerStoryboard(name: "Main")
.lifetime(.lazySingle)
}
}
let globalContainer = DIContainer()
let useCaseContainer = DIContainer()
globalContainer.append(Part.self)
useCaseContainer.append(Part.self)
let storyboard1: UIStoryboard = *globalContainer
let storyboard2: UIStoryboard = *useCaseContainer
/// storyboard1 === storyboard2 - true
But there is a problem, a new ViewController (and all its dependencies too) will be created from the container which was the first. In example globalContainer
.
Unfortunately, DI cannot solve all problems :) But if you've seen a solution to your problem in the other DI then tell me where, and maybe I'll add to your library. The main requirement is that the solution should be universal.
Perhaps you would have helped scope
of autofac: http://autofac.readthedocs.io/en/latest/lifetime/working-with-scopes.html
Most likely I will return them but later when I think of how they successfully make in swift. They rarely need.
Or: https://github.com/ivlevAstef/DITranquillity/issues/83 - It is a universal solution for the most challenging cases. Now in a priority to do it.
Also, you can use a storyboardReference - that is, your VC1,VC2,VC3 can be on one storyboard, and the other VC to the other storyboards. Then, this storyboard may belong to a separate container.
A small cheat:
let globalContainer = DIContainer()
let useCaseContainer = DIContainer()
globalContainer.registerStoryboard(name: "Main")
.lifetime(.lazySingle)
globalContainer.register(VC1.self)
.postInit { $0.object = *useCaseContainer }
globalContainer.register(VC2.self)
.postInit { $0.object = *useCaseContainer }
let yourObject = YourObject()
useCaseContainer.register{ yourObject }
But I do not welcome such a solution.
But I realized that I should add time of life perContainer
: https://github.com/ivlevAstef/DITranquillity/issues/109
From 3.1.2
old case can rewrite on:
let globalContainer = DIContainer()
let useCaseContainer = DIContainer()
globalContainer.registerStoryboard(name: "Main")
.lifetime(.lazySingle)
globalContainer.register(VC1.self)
.postInit { $0.object = *useCaseContainer }
globalContainer.register(VC2.self)
.postInit { $0.object = *useCaseContainer }
useCaseContainer.register(YourObject.init)
.lifetime(.perContainer)
But you have to understand when the container can be destroyed or recreated.
Wow, so quick support 👍
Yeah, the perContainer
scope is a nice addition.
I'm using Dagger 2 for dependency injection in Android. I like their concept of Components and Subcomponents. That's why I was looking for a similar functionality in the DI lib for Swift.
As stated in the docs, there are two main advantages of using subcomponents:
I think, in Swift we can achieve a similar behaviour by using weakSingle
scope as you advised in previous comments.
Activity
in Android or UIViewController
in iOS).Okay, I'll play with perContainer
to see how the architecture can be improved. I'm closing the issue for now.
Hi,
Thank you for the library! It's nice to have a decent DI-library for pure Swift projects.
Could you please clarify a couple of things for me. I'm trying to wrap my head around custom scope objects. Let's say I have three VCs:
VC1 -> VC2 -> VC3
. And I want to share some object between them.I understand, that I can just register the object as single (
.single, .lazySingle
or.weakSingle
). But it will live so long as the whole app. In my case I want to bind its lifecycle to the aforementioned view controllers.What is the best way to achieve this? Should I create another
DIContainer
just for these VCs?