New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added ManualResolver #365
base: master
Are you sure you want to change the base?
added ManualResolver #365
Conversation
…ly defined and used
Can somebody please take a look at this PR? |
Hey Rivukis would you mind to explain why this solution? I'm mean, looking to the implementation the purpose is after you resolve your instance you want to get the reference to this instance and pass / inject any other variable property right? But you implementation already can be done using: Is this what you are looking for or it's different? |
Hey @felipeflorencio, |
Yep, but you still can do the same using init completed, because the initCompleted you receive the initialised instance the same way that you are doing in your implementation. The difference is that swinject does this in two steps, first initialising, and the reason this is to make sure that the instance was fully loaded, for example. Your implementation does this:
The same with that swinject has today would be:
And this work's with all scenarios, if you use NIB, if you need has the same name as your viewcontroller your viewcontroller will initialise your need and will maintain the same reference, but even is not a problem as initCompleted always return the instance that was completely initialised. One of the down sizes, but it's how its works iOS is that we can't have a custom initialiser to inject our dependencies, that's why we need to inject on initCompleted, using method injection or variable injection. Sorry if i'm not seeing the same, but from the source-code that you added I could reproduce the same behaviour using initCompleted @jakubvano What do you think? Can you give us your insigne ? |
The scenarios you described are cases when you are the one calling For instance if you have a custom You can try this yourself if you set up the scenario I just described. Create a subclass of |
As a side note, I'm a big fan of Swinject and still use it. However, I'm a little disappointed that 9 months has gone by without any feedback on my pull request. At this point I feel like the developers are no longer maintaining it and it's in a state of "use at your own risk". |
@Rivukis Maybe you should update your tests to use the scenario you described with a view and a view controller? Then it may be more clear that when something changes, the test fails? |
Thanks for the PR 👍 I'm sorry for taking this long to respond 😓 Even though this kind of functionality is achievable without an explicit Swinject API, IMO it does make sense to bake it in. I would propose a couple of changes though:
Usage I have in mind could look something like this: container.manualInitCompleted(Foo.self) { resolver, foo in // maybe `externalInitCompleted`?
foo.dep1 = resolver.resolve(Dep1.self)
foo.dep2 = resolver.resolve(Dep2.self)
// alternatively, but we don't need to make this idiomatic - leave this on the developer instead
foo.inject(dep1: resolver.resolve(Dep1.self)!, dep2: resolver.resolve(Dep2.self)!)
}
let foo = Foo()
container.inject(foo) What are your thoughts? |
Hi @jakubvano, Thank you for responding! I think those are all great ideas for improving this PR. Unfortunately, I have many projects I'm managing right now and do not have the time to make the updates. If you want to go ahead and make them feel free. Otherwise, I'll get to them "eventually", but fair warning it may be a while. I'd also like to encourage others to make the suggested changes as well, if you have the cycles. |
Hi there, Based on the examples give in the comments, programmer can reference the container from the If the reason to not reference the container is to be able to use mocked dependencies from tests, then programmer should be able to register mocked dependencies in the container before running tests.
Would this work for the View and ViewController use cases? |
Hi @BProg, I gave up on this after 9 months of waiting with no response and decided to move on. It became too difficult and time consuming to try and improve Swinject (i.e. this PR). Since then I treat Swinject as "use at your own risk" since it doesn't seem to be actively maintained (only based on this PR; didn't look at commit/bug history). I have used this solution in my personal projects using a helper cocoapod that I made for myself (thus not having to rely on Swinject maintainers). It's now been another 5 years. I forgot this PR still existed. I don't have any opinions on what happens to it: update it, merge it, delete it. etc. No offense to you (in fact it's nice of you to try and catch up on things long forgotten), but I've given up any hope on contributing to Swinject. |
ManualResolver can be used for types where the initializer can not be manually defined and used. (i.e.
UIViewController
s,UIView
s, etc.)I realize that there is already a solution to this problem for
UIViewController
s usingUIStoryBoard
s. However, this solution only works for that particular case. If the user wants to use a XIB or inject properties into aUIView
then a different solution will be needed. Also, since that solution is using advanced topics in Objective-C, it can be difficult to extend it to cover these other similar scenarios.ManualResolver is one solution that I've used personally. After using it in a couple projects, I thought that others might benefit from this solution as well. Please let me know what you think and/or how this solution could be improved.