所以,我正在重新设计我的Android应用程序以使用Dagger.我的应用程序庞大而复杂,我最近遇到了以下情况:
对象A需要一个特殊的DebugLogger实例,这是一个完美的注入候选者.我可以通过A的构造函数注入它,而不是绕过记录器.这看起来像这样:
class A
{
private DebugLogger logger;
@Inject
public A(DebugLogger logger)
{
this.logger = logger;
}
// Additional methods of A follow, etc.
}
Run Code Online (Sandbox Code Playgroud)
到目前为止这是有道理的.但是,A需要由另一个类B构造.必须构造A的多个实例,所以遵循Dagger的做事方式,我简单地将一个注入Provider<A>
到B中:
class B
{
private Provider<A> aFactory;
@Inject
public B(Provider<A> aFactory)
{
this.aFactory = aFactory;
}
}
Run Code Online (Sandbox Code Playgroud)
好的,到目前为止还不错.但等等,突然A需要额外的输入,例如一个称为"数量"的整数,这对于它的构造至关重要.现在,我的A构造函数需要如下所示:
@Inject
public A(DebugLogger logger, int amount)
{
...
}
Run Code Online (Sandbox Code Playgroud)
突然,这个新参数干扰了注射.而且,即使这确实有效,除非我弄错了,否则在从提供者检索新实例时我无法传递"金额".我可以在这里做几件事,我的问题是哪一个是最好的?
我可以通过添加一个setAmount()
预期在构造函数之后调用的方法来重构A. 然而,这是丑陋的,因为它迫使我延迟A的构造直到"数量"被填入.如果我有两个这样的参数,"数量"和"频率",那么我将有两个安装者,这将意味着要么复杂的检查以确保在调用两个setter之后恢复A的构造,或者我将不得不在混合中添加第三个方法,如下所示:
(Somewhere in B):
A inst = aFactory.get();
inst.setAmount(5);
inst.setFrequency(7);
inst.doConstructionThatRequiresAmountAndFrequency();
Run Code Online (Sandbox Code Playgroud)
另一种选择是我不使用基于构造函数的注射并使用基于场的注射.但现在,我必须把我的田地公之于众.这对我来说并不合适,因为现在我有义务将我班级的内部数据透露给其他班级.
到目前为止,我能想到的唯一优雅的解决方案是为提供者使用基于字段的注入,如下所示:
class A
{
@Inject
public Provider<DebugLogger> loggerProvider; …
Run Code Online (Sandbox Code Playgroud) 我希望这只是我在这里做错了.我正在尝试使用Dagger 2.0为我的JUnit测试注入依赖项(不是Espresso测试,只是纯JUnit).所以,我有一个'主'java模块和'测试'java模块.在主模块中,我有一个Dagger模块和一个组件:
@Module
public class MainModule {
@Provides
public Widget provideWidget() {
return new ConcreteWidget();
}
}
...
@Component (modules = MainModule.class)
public interface MainComponent {
void inject(WidgetConsumer consumer);
}
Run Code Online (Sandbox Code Playgroud)
在我的测试模块中,我有以下内容:
@Module
public class TestModule {
@Provides public Widget provideWidget() {
return new Widget() {
@Override
public void doThing() {
int y = 6;
y ++;
}
};
}
}
...
@Component(modules = TestModule.class)
public interface TestComponent extends MainComponent{
}
Run Code Online (Sandbox Code Playgroud)
我的build.gradle有依赖关系,如下所示:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) …
Run Code Online (Sandbox Code Playgroud) 我的公司管理员在写这个问题时刚刚找到了这个问题的答案,所以我在这里发布给其他人:
我使用xfreerdp从Linux连接到带有RDP的Windows 7机器.通常,我提供我的凭据和机器的IP地址,一切正常.有一天,我进来试图连接,只是为了呈现这个:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the host key sent by the remote host is
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
Run Code Online (Sandbox Code Playgroud)
(在X的是实际的数字).我检查了我的Linux known_hosts文件为我连接到本机,是的,的确,RSA指纹的机器的确发生了变化.所以我问我公司的管理员他是否做了一些更新或任何会改变Windows用于RDP会话的关键内容.他说没有任何改变,他知道.在这一点上,常识和我的安全知识告诉我,在我实际登录机器并检查确实有一个新的RDP主机密钥之前,我不应该连接.(如果没有,那么很可能会发生中间人攻击.)
问题是,当我登录到物理机器以查明RSA密钥是否已更改时,我无法确定要查看它的位置.我在网上搜索,无法在Windows 7中找出任何方式来查看关键RDP会话使用的RSA指纹.有谁知道我可以在哪里查看密钥?