Как использовать Guice Assisted Inject для этого фабричного образца? - PullRequest
2 голосов
/ 07 мая 2019

Ниже приведен фабричный шаблон, который я написал.Но, чтобы превратить его в провайдера, Guice документация не совсем помогает.

class ClientA extends AbstractClient {...}
class ClientB extends AbstractClient {...}
class ClientUtil {
        private static AbstractClient client;
        public static AbstractClient getClient(String key) {
            ClientType clientType = ....
            switch(clientType) {
                case ".." : client = new ClientA.Builder()....build();
                            break;
                case "..." :
                default : client= new ClientB.Builder()....build();
            }
            return client;
        }
}
class Application {
        AbstractClient client = ClientUtil.getClient(key);  // here, key is a string which is dynamic
    }

Пожалуйста, предоставьте несколько советов о том, как это можно записать в формате Provider с Guice AssistedInject.

Ответы [ 2 ]

1 голос
/ 10 мая 2019

Прежде всего, я бы определенно согласился с @Lesiak. Код client= new ClientB.Builder()....build(); неясен, поскольку многоточие может содержать любое количество полей, которые вы устанавливаете на ClientA / B.

Но чтобы дать вам пример того, как использовать AssistedInject для вашего конкретного экземпляра:

class ClientA extends AbstractClient {
    @Inject
    public ClientA(ServiceOne serviceOne,
            ServiceTwo serviceTwo,
            @Assisted MyObject myObject) {
        ...
    }
}

class ClientB extends AbstractClient {
    // Same constructor as ClientA
}

Ваш завод будет выглядеть примерно так:

interface ClientFactory {
    @Named("ClientA") public AbstractClient getClientA(...);
    @Named("ClientB") public AbstractClient getClientB(...);
} 

Ваши параметры могут быть разными объектами или чем угодно, но по сути они должны совпадать с аннотацией конструктора @Assisted. Теперь вы можете понять, почему @Lesiak предоставил ответ, который он дал, если ваш компоновщик устанавливает 10 полей на ClientA, тогда ваш фабричный метод должен иметь 10 параметров метода, и он очень неуправляем.

Затем вы бы использовали это с:

@Inject ClientFactory clientFactory;

...
AbstractClient client = clientFactory.getClientA(something, something1, ...);
...
1 голос
/ 07 мая 2019

Вы пытались написать свою Фабрику вручную? В руководстве, которое вы связали, есть хороший пример, и ваш код будет легко переведен на Guice.

public interface ClientFactory {
    AbstractClient create(String key);
}

public class ClientFactoryImpl implements ClientFactory {
    @Override
    public AbstractClient create(String key) {
        if ("A".equals(key)) {
            return new ClientA();
        } else {
            return new ClientB();
        }
    }
}

и привязка фабрики к реализации

bind(ClientFactory.class).to(ClientFactoryImpl.class);

AssistedInject наносит ущерб в вашем случае. Все, что он предлагает, - это создание ClientFactoryImpl автоматически. Реализация только передает введенные и вспомогательные аргументы в конструктор. Но у вас есть некоторая нетривиальная логика в методе создания. В этом случае я предлагаю вам создать реализацию фабрики самостоятельно.

...