MVP with CDI; avoiding circular dependency

后端 未结 4 1690
别那么骄傲
别那么骄傲 2021-01-12 02:03

I try to build a Webapp with the MVP paradigm. Because I want the API to be clean and make everything easy testable I try to inject everything possible via Contructor Inject

相关标签:
4条回答
  • 2021-01-12 02:12

    Try to move injection points from constructor to properties. So annotate properties with @Injection, not constructor. I think this way weld first creates instances of classes and only then injects dependencies. And replace your constructor with default.
    If you annotate constructor weld needs to have instance of View when on creating Presenter, but to create View he needs Presenter. With default constructor and annotated properties it can create both View and Presenter and only then inject them to each other.

    0 讨论(0)
  • 2021-01-12 02:26

    There's some approaches to solve circular dependency, but when this kind of exception is thrown note that could be something wrong with your architecture.

    But consider see this answer

    0 讨论(0)
  • 2021-01-12 02:29

    It seems to me that Vaadin has nothing to do with the problem.

    There may be (probably) a circular dependency injection problem but the problem lies in the ClassNotFoundException. What application server are you deploying to? Is it a full fledged Java EE 6 AS? If not, perhaps you're missing some libraries in your deployment.

    0 讨论(0)
  • 2021-01-12 02:39

    I got it to work now. The hint from Nikita Beloglazov helped a lot because as I understand it the problem really is the moment when the instantiation is done. As I want to stay with the constructor injection I chose the second approach:

    public Class PresenterImpl implements Presenter {
    
    private ViewImpl view;
    private Instance<ViewImpl> instanceView;
    private User user;
    
    @Inject
    public PresenterImpl(Instance<ViewImpl> instanceView, User user) {
       this.instanceView = instanceView;
       this.user = user;
    
       bind();
    }
    
    public void bind() {
       this.view = instanceView.get();
    }
    
    public void fetchNames() {
       fetchFromDB();
       view.setUser(user);
    }
    }
    

    To get this to work I have to inject only a proxy object at the time of constructor injection and get the real instance at the moment when the first action on the object is performed. This is the normal behavior of normal scoped beans. So I made the presenter and the view @SessionScoped and extended the interfaces from Serializable. Now the Constructor injection works and the ViewImpl is "lazy injected".

    0 讨论(0)
提交回复
热议问题