Break cyclic dependency to use dependency injection

I just started using dagger 2 and had not used any other dependency injection infrastructures before. Now I am fixated on cyclic dependence, and I do not know how to solve it correctly. Consider an example in a server application that uses a Reactor template with Java NIO:

I have a Handler object attached to a selection key, which is executed when new information arrives on the network:

 class Handler implements Runnable { Server server; Client client; public void run { // static factory method that eventually calls a method on server, passing in 'client' as argument Command.parse(input).execute(server, client); } public void send(String string) { // enqueu string and inform reactor about interest in sending } } 

The Client class contains some state of the connected client. All connected clients are managed in the Server class.

 class Client { Handler h; public send(String response) { h.send(response); } } 

When a new entry arrives, Handler creates Command objects, executes them on the server, and the server will ultimately respond to the client.

So what I'm doing right now is creating a Client object manually in Handler , passing the this link to be able to send a response:

 client = new Client(this); 

So my question is: is there something wrong with the design? Is it possible to separate Client and Handler ? Or should I just live with it and not use dependency injection everywhere ?

I appreciate your suggestions

+5
source share
2 answers

I realized that what I was really trying to solve did not break the dependencies between Client and Handler , but rather used dependency injection instead of the new operator.

The solution I was looking for: ClientFactory a ClientFactory into the Handler constructor and use clientFactory.create(this) to create the Client object. The brilliant AutoFactory library allows you to create such a factory with a simple @AutoFactory annotation. The constructor of the created class is automatically annotated using @Inject .

+2
source

If you want the client to be able to send the message back through the handler, the following might break your loop:

 // lives in a common package both classes access public interface ResponseClass { public void sendSomeMessage(String message); } public class Handler { // handler can also implement ResponseClass directly but I prefer using an additional class for flexibility. public void whenYouCreateClient() { Client client = new Client(new HandlerWrapper(this)); } public static class HandlerWrapper implements ResponseClass { private final Handler handler; public HandlerWrapper(Handler handler) { this.handler = handler; } public void sendSomeMessage(String message) { handler.send(message); } } public void send(String string) { // enqueu string and inform reactor about interest in sending } } public class Client { ResponseClass rc; // naming should be improved :) public void sendMessage(String message) { rc.sendSomeMessage(message); } } 

Currently, your classes are still related to each other, but as far as your design is related to your client, it is tied only to a common ResponseClass.

you can have a hierarchy like:

common <- client <- handler

where the handler knows the client and the general and the client only knows about the general. (assuming you put the interface in a shared package)

instead of client ↔ handler

I deliberately used sendSomeMessage to emphasize that this is a different method that you call on the wrapper / interface, but of course you can name them as you like.

One note: I did not use dagger2, so I can’t say for sure that what I do can be done using this product, but that’s how I would separate this cyclic dependency

+3
source

Source: https://habr.com/ru/post/1212102/


All Articles