Dagger 2 组件中 getter 方法的用途是什么?
What is the purpose of the getter methods in Components in Dagger 2?
我正在尝试了解 Dagger 2 中的组件。这是一个示例:
@Component(modules = { MyModule.class })
public interface MyComponent {
void inject(InjectionSite injectionSite);
Foo foo();
Bar bar();
}
我了解 void inject()
方法的作用。但我不明白其他 Foo foo()
getter 方法的作用。这些其他方法的目的是什么?
在依赖组件中的使用
在依赖组件层次结构的上下文中,例如 this example,提供方法(例如 Foo foo()
用于向依赖项公开绑定零件。 “公开”意味着“提供”甚至“发布”。请注意,方法本身的名称实际上是无关紧要的。一些程序员选择将这些方法命名为 Foo exposeFoo()
以使方法名称反映其用途。
解释:
当您在 Dagger 2 中编写组件时,您会将包含 @Provides
方法的模块组合在一起。这些 @Provides
方法可以被认为是“绑定”,因为它们将抽象(例如,类型)与解析该类型的具体方法相关联。考虑到这一点,Foo foo()
方法使组件能够将其对 Foo
的绑定公开给依赖组件。
示例:
假设 Foo
是一个应用程序单例,我们希望将其用作 DependsOnFoo
实例的依赖项,但在范围较窄的组件内。如果我们在 MyDependentComponent
的模块之一中编写一个简单的 @Provides
方法,那么我们将获得一个新实例。相反,我们可以这样写:
@PerFragment
@Component(dependencies = {MyComponent.class }
modules = { MyDependentModule.class })
public class MyDependentComponent {
void inject(MyFragment frag);
}
和模块:
@Module
public class MyDepedentModule {
@Provides
@PerFragment
DependsOnFoo dependsOnFoo(Foo foo) {
return new DependsOnFoo(foo);
}
}
还假设 DependentComponent
的注射部位包含 DependsOnFoo
:
public class MyFragment extends Fragment {
@Inject DependsOnFoo dependsOnFoo
}
注意 MyDependentComponent
只知道模块 MyDependentModule
。通过该模块,它知道它可以使用 Foo
的实例提供 DependsOnFoo
,但它不知道如何自己提供 Foo
。尽管 MyDependentComponent
是 MyComponent
的依赖组件,但还是会发生这种情况。 MyComponent
中的Foo foo()
方法允许依赖组件MyDependentComponent
使用MyComponent
对Foo
的绑定来注入DependsOnFoo
。没有这个Foo foo()
方法,编译会失败
用于解析绑定
假设我们想要获取 Foo
的实例而无需调用 inject(this)
。组件内的 Foo foo()
方法允许使用与使用 Guice 的 Injector
or Castle Windsor's Resolve
调用 getInstance()
相同的方法。图示如下:
public void fooConsumer() {
DaggerMyComponent component = DaggerMyComponent.builder.build();
Foo foo = component.foo();
}
Dagger 是一种连接对象及其依赖关系图的方法。作为直接调用构造函数的替代方法,您可以通过从 Dagger 请求它们来获取实例,或者通过提供您希望注入 Dagger 创建的实例的对象。
让我们开一家咖啡店,这取决于 Provider<Coffee>
和 CashRegister。假设您将这些连接到一个模块中(可能连接到 LightRoastCoffee 和 DefaultCashRegister 实现)。
public class CoffeeShop {
private final Provider<Coffee> coffeeProvider;
private final CashRegister register;
@Inject
public CoffeeShop(Provider<Coffee> coffeeProvider, CashRegister register) {
this.coffeeProvider = coffeeProvider;
this.register = register;
}
public void serve(Person person) {
cashRegister.takeMoneyFrom(person);
person.accept(coffeeProvider.get());
}
}
现在您需要获取该 CoffeeShop 的实例,但它只有一个带有依赖项的双参数构造函数。那么你是怎么做到的呢?很简单:您告诉 Dagger 使 工厂方法 在它生成的 Component 实例上可用。
@Component(modules = {/* ... */})
public interface CoffeeShopComponent {
CoffeeShop getCoffeeShop();
void inject(CoffeeService serviceToInject); // to be discussed below
}
当您调用 getCoffeeShop
时,Dagger 创建 Provider<Coffee>
来提供 LightRoastCoffee,创建 DefaultCashRegister,将它们提供给 Coffeeshop 构造函数,然后 returns 您得到结果。恭喜,您是一家全线咖啡店的骄傲主人。
现在,所有这些都是替代 void
注入方法,它采用已创建的实例并注入其中:
public class CoffeeService extends SomeFrameworkService {
@Inject CoffeeShop coffeeShop;
@Override public void initialize() {
// Before injection, your coffeeShop field is null.
DaggerCoffeeShopComponent.create().inject(this);
// Dagger inspects CoffeeService at compile time, so at runtime it can reach
// in and set the fields.
}
@Override public void alternativeInitialize() {
// The above is equivalent to this, though:
coffeeShop = DaggerCoffeeShopComponent.create().getCoffeeShop();
}
}
所以,你有它:两种不同的风格,这两种风格都可以让你访问完全注入的对象图,而无需列出或关心它们究竟需要哪些依赖项。您可以选择一个或另一个,或者更喜欢顶层的工厂方法和 Android 或服务用例的成员注入,或任何其他类型的混合和匹配。
(注意: 除了用作对象图的入口点之外,称为 提供方法 的无参数吸气剂也很有用用于公开组件依赖项的绑定,正如 David Rawson 在 中所描述的那样。)
我正在尝试了解 Dagger 2 中的组件。这是一个示例:
@Component(modules = { MyModule.class })
public interface MyComponent {
void inject(InjectionSite injectionSite);
Foo foo();
Bar bar();
}
我了解 void inject()
方法的作用。但我不明白其他 Foo foo()
getter 方法的作用。这些其他方法的目的是什么?
在依赖组件中的使用
在依赖组件层次结构的上下文中,例如 this example,提供方法(例如 Foo foo()
用于向依赖项公开绑定零件。 “公开”意味着“提供”甚至“发布”。请注意,方法本身的名称实际上是无关紧要的。一些程序员选择将这些方法命名为 Foo exposeFoo()
以使方法名称反映其用途。
解释:
当您在 Dagger 2 中编写组件时,您会将包含 @Provides
方法的模块组合在一起。这些 @Provides
方法可以被认为是“绑定”,因为它们将抽象(例如,类型)与解析该类型的具体方法相关联。考虑到这一点,Foo foo()
方法使组件能够将其对 Foo
的绑定公开给依赖组件。
示例:
假设 Foo
是一个应用程序单例,我们希望将其用作 DependsOnFoo
实例的依赖项,但在范围较窄的组件内。如果我们在 MyDependentComponent
的模块之一中编写一个简单的 @Provides
方法,那么我们将获得一个新实例。相反,我们可以这样写:
@PerFragment
@Component(dependencies = {MyComponent.class }
modules = { MyDependentModule.class })
public class MyDependentComponent {
void inject(MyFragment frag);
}
和模块:
@Module
public class MyDepedentModule {
@Provides
@PerFragment
DependsOnFoo dependsOnFoo(Foo foo) {
return new DependsOnFoo(foo);
}
}
还假设 DependentComponent
的注射部位包含 DependsOnFoo
:
public class MyFragment extends Fragment {
@Inject DependsOnFoo dependsOnFoo
}
注意 MyDependentComponent
只知道模块 MyDependentModule
。通过该模块,它知道它可以使用 Foo
的实例提供 DependsOnFoo
,但它不知道如何自己提供 Foo
。尽管 MyDependentComponent
是 MyComponent
的依赖组件,但还是会发生这种情况。 MyComponent
中的Foo foo()
方法允许依赖组件MyDependentComponent
使用MyComponent
对Foo
的绑定来注入DependsOnFoo
。没有这个Foo foo()
方法,编译会失败
用于解析绑定
假设我们想要获取 Foo
的实例而无需调用 inject(this)
。组件内的 Foo foo()
方法允许使用与使用 Guice 的 Injector
or Castle Windsor's Resolve
调用 getInstance()
相同的方法。图示如下:
public void fooConsumer() {
DaggerMyComponent component = DaggerMyComponent.builder.build();
Foo foo = component.foo();
}
Dagger 是一种连接对象及其依赖关系图的方法。作为直接调用构造函数的替代方法,您可以通过从 Dagger 请求它们来获取实例,或者通过提供您希望注入 Dagger 创建的实例的对象。
让我们开一家咖啡店,这取决于 Provider<Coffee>
和 CashRegister。假设您将这些连接到一个模块中(可能连接到 LightRoastCoffee 和 DefaultCashRegister 实现)。
public class CoffeeShop {
private final Provider<Coffee> coffeeProvider;
private final CashRegister register;
@Inject
public CoffeeShop(Provider<Coffee> coffeeProvider, CashRegister register) {
this.coffeeProvider = coffeeProvider;
this.register = register;
}
public void serve(Person person) {
cashRegister.takeMoneyFrom(person);
person.accept(coffeeProvider.get());
}
}
现在您需要获取该 CoffeeShop 的实例,但它只有一个带有依赖项的双参数构造函数。那么你是怎么做到的呢?很简单:您告诉 Dagger 使 工厂方法 在它生成的 Component 实例上可用。
@Component(modules = {/* ... */})
public interface CoffeeShopComponent {
CoffeeShop getCoffeeShop();
void inject(CoffeeService serviceToInject); // to be discussed below
}
当您调用 getCoffeeShop
时,Dagger 创建 Provider<Coffee>
来提供 LightRoastCoffee,创建 DefaultCashRegister,将它们提供给 Coffeeshop 构造函数,然后 returns 您得到结果。恭喜,您是一家全线咖啡店的骄傲主人。
现在,所有这些都是替代 void
注入方法,它采用已创建的实例并注入其中:
public class CoffeeService extends SomeFrameworkService {
@Inject CoffeeShop coffeeShop;
@Override public void initialize() {
// Before injection, your coffeeShop field is null.
DaggerCoffeeShopComponent.create().inject(this);
// Dagger inspects CoffeeService at compile time, so at runtime it can reach
// in and set the fields.
}
@Override public void alternativeInitialize() {
// The above is equivalent to this, though:
coffeeShop = DaggerCoffeeShopComponent.create().getCoffeeShop();
}
}
所以,你有它:两种不同的风格,这两种风格都可以让你访问完全注入的对象图,而无需列出或关心它们究竟需要哪些依赖项。您可以选择一个或另一个,或者更喜欢顶层的工厂方法和 Android 或服务用例的成员注入,或任何其他类型的混合和匹配。
(注意: 除了用作对象图的入口点之外,称为 提供方法 的无参数吸气剂也很有用用于公开组件依赖项的绑定,正如 David Rawson 在