L3K0V
L3K0V

Reputation: 1134

Dependency Injection of factory of objects

If we have several classes looks like:

@Device()
@Model("some model")
@Variant("A")
public class SomeModelVariantA extends BaseDevice {

    public SomeModelVariantA (InputStream in, OutputStream out, int encoding) throws IOException {
        super(in, out, encoding);
    }

    @Override
    @CommandSpec("41")
    @WithoutArguments
    @WithoutResponse
    public Response init(Command args) throws NotSupportedException, IOException {
        return null;
    }

I generate class implementation using JavaPoet and annotation processing. I have project for all annotations I use, project compiler which have Annotation processor to handle annotated classes and Application project with annotated, generated classes and other logic. All generated classes extends base BaseDevice class and looks like:

/**
 * Generated on Fri Aug 28 11:03:21 EEST 2015
 */
public final class SomeModelVariantA extends BaseDevice {
  public SomeModelVariantA (InputStream arg0, OutputStream arg1, int arg2) throws IOException {
    super(arg0, arg1, arg2);
  }

  @Override
  public Response init(Command arg0) throws NotSupportedException, IOException {
    StringBuilder builder = new StringBuilder("");
    Response response = new Response();

    customCommand(41, builder.toString());
    return response;
  }

I have generated several concrete devices and next step is to create an api working with these devices.

public class Api {

    BaseDevice device;

    Api(String device, InputStream is, OutputStream os, int encoding) {
        if ("SomeModelVariandA1".contentEquals(device)) {
            device = new SomeModelVariantA(is, os, encoding);
        }
        ... else if for other devices
    }

    public void callInit() {
        device.init(null);
    }
}

So how can I generate factory for all devices and inject device by some String name into the Api class. How can I handle providing a device created with input and output stream from the api constructor. Is dagger 2 and google auto factory suitable for this purpose and can someone provide an example usage.

Thanks

Upvotes: 0

Views: 223

Answers (1)

Squeez
Squeez

Reputation: 959

You need to set to concreteClass full class name (package+class name) and then use Class.forName(concreteClass)

For example, if you have ClassA defined in com.blablabla.classes package, you need to set to concreteClass value "com.blablabla.classes.ClassA". Then, if you want to create class-objects only which extends BaseClass, you need to define new class like this:

Class<T extends BaseClass> injectedClass = Class.forName(concreteClass); Or, if you want to create all class-objects, you need to define:

Class injectedClass = Class.forName(concreteClass);

Upvotes: 0

Related Questions