Swinject: How I can inject in subclass UIView

Created on 3 Jun 2016  路  23Comments  路  Source: Swinject/Swinject

I need inject dependency in subclass from UITableViewCell, so how I can do it?
And how I should inject in subclass from UIView if I use IB?

question

Most helpful comment

Hi guys,
Are there any updates on resolving dependencies for views that are loaded from storyboards/xibs?

All 23 comments

Hi @ajjnix. The following example project might be helpful to investigate how to use Swinject in the cases.
https://github.com/Swinject/SwinjectMVVMExample

@yoichitgy thanks for your answer, I looked here previously (but I look it again). In Typhoon (objc) I can inject my classes in view but I can't see how I can do it in Swinject. Of course I can inject it from ViewController or from somewhere else (from example project: ControllerViewModel inject to CellViewModel) but it were clear inject it from assembly

Does the feature of Typhoon have documentation? If you give me its link, I might be able to answer its corresponding feature of Swinject or a workaround.

@yoichitgy In documentation have example in section: Circular dependencies with injection dependency components in View

@ajjnix, thanks for the link! Swinject supports circular dependencies, but let me take time to answer something good for your case. I think I still don't understand your question.

@yoichitgy link for not about circular dependencies, only for demonstration necessity injection in view.
In example injection delegate in JobExecutionView (subclass UIView).
This topic about injection dependency inside UIView and subclass.
In now we can't do it in Swinject, or I just don't see it.

You wrote "if I use IB". Which do you use, storyboard or xib?

I'm sorry that I couldn't catch the point of your question馃槩 If you use NIB/XIB, Issue #95 might be helpful. If you use Storyboard, https://github.com/Swinject/SwinjectStoryboard/issues/5 might be helpful.

@yoichitgy Sorry, I try write my question more details ((

For example I have UserAvatar: UIView (UserAvatar.xib)
ProfileController used UserAvatar (and add from storyboard like UI class)
UserAvatar have dependency from UserService (method downloadAvatar)

So I want resolve this dependency using Swinject and I see only one way for it:
inject UserService to UserAvatar from ProfileController (or ViewModel)

But I want way for configurate dependency for my UI classes from assembly. Like I did it use Typhoon on objc.

@ajjnix thanks for adding the example馃槂 I've never tried SwinjectStoryboard containing a view defined in an XIB. I need some investigation to answer.

@yoichitgy @ajjnix I have the same issue. Did you find any solution?

@lisardo, not yet on my side. I'm sorry but I still couldn't take time to investigate this issue. For now my first priority is implementing features for Swinject v2, then the other issues.

@ajjnix, I'm going to take time to understand the problem. Could you write UserAvatar, ProfileController, UserService code without DI and make UserAvatar.xib and ProfileController.storyboard? I would like to understand your requirement correctly, then I'll think how the requirement can be achieved with Swinject.

@lisardo, maybe could you provide those implementation and xib/storyboard if you see the same issue?

@yoichitgy
I write simple project for show UI dependency problem. It's not case before but similar and I think more complex.
I have UserTableViewCell with AsyncImageView. It's like easy but AsyncImageView have dependency from protocol ImageLoader and I need inject implementation ImageLoader inside AsyncImageView from UserTableViewCell.

So I have next relations:
UserTableViewCell -> AsyncImageView -> implementation ImageLoader

Swinject_problem_xib.zip

Thanks @ajjnix for making the sample project馃槂 I'm going to check it and answer shortly.

@ajjnix, hi. I have the same issue and now I solved it this way:

Create and register ViewFactory:

class ViewFactory: ViewFactoryProtocol {

    fileprivate var container: Container!

    init(container: Container) {
        self.container = container
    }

    // MARK: - ViewFactoryProtocol

    func view<View>(type: View.Type) -> View? {
        return container.resolve(type)
    }
}

container.register(ViewFactory.self) { _ in
    return ViewFactory(container: container)
}.inObjectScope(.container)

Create and register MyView:

class MyView: UIView {
    var name: String!
}

container.register(MyView.self) { r in
    let myView = MyView()
    myView.name = "MyName"
    return myView
}

And use:

if let myView = viewFactory.view(type: MyView.self) {
    Log.info("MyView -> \(myView.name)") // MyView -> Optional("MyName")
}

@Beniamiiin, in the following your code...
container.register(ViewFactory.self) { _ in return ViewFactory(container: container) }.inObjectScope(.container)
you pass Container into ViewFactory. I might be wrong, but probably more (architecturally?) correct will be passing instance of Resolver (the one which is _ in the code) instead of container.
Here is what I mean:
container.register(ViewFactory.self) { resolver in return ViewFactory(resolver: resolver) }.inObjectScope(.container)
You know, you only resolve in the factory, so strictly speaking you don't need full-fledged container functionality. Does it make sense?

@serges147 yes, you are right, pass instance of Resolver it will be more correctly, thank you :)

It will be work, but I don't want to use Factory or Container inside my ViewController and create view from code. I just want to get my cell from storyboard or xib like ViewController with all dependency.

@ajjnix, I'm sorry for taking long time to answer to this question.

The problem here is that instantiation of UserTableViewCell is made by tableView.dequeueReusableCellWithIdentifier, which does not use a Swinject container to create an instance. If the method uses a Swinject container, the dependency can be injected automatically as configured to the container. The problem might be solved if we have some method swizzling of the method in SwinjectStoryboard project. If we don't have that swizzling, I will write code like @Beniamiiin's.

Please feel free to reopen this issue if the issue is not resolved.

Hi guys,
Are there any updates on resolving dependencies for views that are loaded from storyboards/xibs?

Any updates ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oronbz picture oronbz  路  3Comments

grzegorzkrukowski picture grzegorzkrukowski  路  7Comments

igorkotkovets picture igorkotkovets  路  7Comments

Mackarous picture Mackarous  路  4Comments

Mijail picture Mijail  路  6Comments