Skip to content

Reduce code bloat for multiple instances of the same PrivateGinModule #200

Description

@GoogleCodeExporter
What steps will reproduce the problem?

1. Create a hierarchy of classes which you need to bind to the same interface 
with different parameterizing type:

public interface MyInterface<T>
{
     void doSomething();
}

public class MyInterfaceImpl<T> implements MyInterface<T>
{
    //External services (usually singletons), defined in a global GinModule
    @Inject
    Service1 service1;
    @Inject
    Service2 service2;


    //some base logic
}

public class MyInterfaceStringImpl extends MyInterfaceImpl<String>
{
    //some logic for String implementation
}

public class MyInterfaceIntegerImpl extends MyInterfaceImpl<Integer>
{
    //some logic for Integer implementation
}

public class MyInterfaceDoubleImpl extends MyInterfaceImpl<Double>
{
    //some logic for Double implementation
}


2. Make PrivateGinModule which exposes interface with different parameterizing 
type:

public class MyPrivateGinModule<T> extends PrivateGinModule
{
    private final Class<T> param;
    private Class<? extends MyInterface<T>> implementation;

    public MyPrivateGinModule(Class<T> param)
    {
        this.param=param;
    }

    public MyPrivateGinModule<T> setImplementation(Class<? extends MyInterface<T>> implementation)
    {
        this.implementation=implementation;
        return this;
    }

    protected void configure()
    {
       ...
       bind(typeLiteral(MyInterface.class, param)).to(implementation);
       expose(typeLiteral(MyInterface.class, param));
       //typeLiteral is utility method which makes TypeLiteral<MyInterface<T>> during rebind phase using Types.newParameterizedType() and TypeLiteral.get()
    }
}


3. Install several instances of that module:

public class MyGlobalGinModule extends AbstractGinModule
{
    protected void configure()
    {
        install(new MyPrivateGinModule<Integer>(Integer.class).setImplementation(MyInterfaceIntegerImpl.class));// now we can @Inject MyInterface<Integer>
        install(new MyPrivateGinModule<String>(String.class).setImplementation(MyInterfaceStringImpl.class));// now we can @Inject MyInterface<String>
        install(new MyPrivateGinModule<Double>(Double.class).setImplementation(MyInterfaceDoubleImpl.class));// now we can @Inject MyInterface<Double>
    }
}


4. Compile the code.


What is the expected output? What do you see instead?

Each installed instance of MyPrivateGinModule generates fragments for 
dependencies defined inside - that's OK.
But also it generates fragments for all external dependencies (Service1 and 
Service2) which do not differ from one MyPrivateGinModule instance bindings to 
another.
That causes a lot of duplication in generated code and increases total size of 
compiled js-code.

Original issue reported on code.google.com by rx303...@gmail.com on 25 Sep 2014 at 9:32

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions