在初始化类之后,使用Dagger 2解析命名依赖项

时间:2016-04-28 12:59:26

标签: java dependency-injection dagger-2

我正在使用Dagger 2来管理我的Java应用程序。

我有以下结构:

public interface SecondaryService 
{
    void doSomethingElse(String data);
}

public class SecondaryServiceFirstImpl implements SecondaryService 
{
    public void doSomethingElse(String data)
    {
       // Do something else
    }
}

public class SecondaryServiceSecondImpl implements SecondaryService 
{
    public void doSomethingElse(String data)
    {
       // Do something else
    }
}

public interface MainInterface
{
    void doSomething(String data);
}

public class MainService implements MainInterface
{
    private SecondaryService secondaryService;
    private DatabaseService databaseService;
    public MainService(SecondaryService secondaryService, DatabaseService databaseService)
    {
       this.secondaryService = secondaryService;
       this.databaseService = databaseService;
    }

  public  void doSomething(String data)
  {
     String name = databaseService.getName(data);

    // Resolve the NAMED SecondaryService based on the name property and
    // use the implementation.
  }
}

这是Dagger模块代码:

@Module
public class DependencyRegisterModule
{
    @Provides @Named('first')
    SecondaryService provideSecondaryServiceFirstImpl ()
    {
        return new SecondaryServiceFirstImpl ();
    }

    @Provides @Named('second')
    SecondaryService provideSecondaryServiceSecondImpl ()
    {
        return new SecondaryServiceSecondImpl ();
    }

    @Provides
    DatabaseService provideDatabaseService ()
    {
        return new DatabaseServiceImpl();
    }

    @Provides
    MainInterface provideMainInterface(SecondaryService secondaryService, DatabaseService databaseService)
    {
        return new MainService (secondaryService, );
    }
}

如您所见,我有一个SecondaryService接口,由两个类实现。我想基于一个参数来解析SecondaryService的命名依赖项,我从MainService中的方法中的数据库中获取该参数。

有办法做到这一点吗?如果这不适用于Named依赖项,还有另一种方法吗?

到目前为止,我已经使用了工厂模式,但是很难管理,因为我必须在构造函数中传递类的依赖项。

1 个答案:

答案 0 :(得分:0)

如果您需要2个相同类型的对象,则可以使用

@Named - 或@Qualifiers。注入String usernameString email。在这种情况下,可以使用限定符来区分这些对象。

在您的情况下,似乎您希望 一个对象另一个。在您的情况下,如果您想采用干净的方法,或者在构造函数中为模块添加if / else,则应使用不同的模块。

使用基类

@Module
public abstract class ServiceModule {
    @Provides
    public abstract SecondaryService providesServcie();
}

然后只创建该模块的2个子类并分别提供所需的服务。

创建组件时,只需提供模块的正确实现

if(1 == 1)
    new MyComponent.Builder().add(new OneServiceModule()).build();
else
    new MyComponent.Builder().add(new OtherServiceModule()).build();

请记住,您不必复制其他@Provides方法,因为您可以在组件中使用多个模块。

使用if / else构造

@Module
public class DependencyRegisterModule
{
    private int whichModule;

    public DependencyRegisterModule(int whichModule) {
        this.whichModule = whichModule;
    }

    @Provides
    SecondaryService provideSecondaryServiceSecondImpl ()
    {
        return whichModule == 1 ? new SecondaryServiceSecondImpl() : new SecondaryServiceFirstImpl();
    }
}

我希望我不必解释if / else是如何工作的;)