Dagger - 从其他类访问Singleton对象(Dagger - Accessing Singleton object from other class)
我一直在努力理解并设置Dagger来处理Android项目的依赖注入。 我的单一(没有双关语)目标是创建我可以在我的应用程序中访问的单例对象。 我已经在初始活动中成功设置了对象。 我被困在哪里是从其他类访问这些对象。 这是我到目前为止的设置:
初始App活动
public class SplashScreenActivity extends AppCompatActivity { @Inject SessionKeyExchangerService exchangerService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash_screen); AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build(); // establish the session id as a singleton object exchangerService = component.provideSessionKeyExchangerService(); // test whether I can access the singleton from another class exchangerService.sendEncryptedKeyToServer(); }
组件类
@Singleton @Component(modules = {AppModule.class}) public interface AppComponent { SessionKeyExchangerService provideSessionKeyExchangerService(); AESCipherService provideCipherService(); }
模块类
@Module public class AppModule { @Provides @Singleton AESCipherService provideCipherService() { return new AESCipherService(); } @Provides @Singleton SessionKeyExchangerService provideSessionKeyExchangerService(AESCipherService service) { return new SessionKeyExchangerService(service); } }
AESCipherService
public class AESCipherService { private Long sessionId; public AESCipherService() { sessionId = makeSessionId(); Log.d(Constants.TAG, "Session ID: " + Long.toString(sessionId)); } private Long makeSessionId() { // this generates a random unsigned integer in the space {0, 2^32-1) Random random = new Random(); return random.nextLong() & 0xffffffffL; } public Long getSessionId() { return sessionId; } }
SessionKeyExchanger类
public class SessionKeyExchangerService { private static SessionKeyExchangerService exchanger; private AESCipherService cipherService; @Inject public SessionKeyExchangerService(AESCipherService cipherService) { this.cipherService = cipherService; } public void sendEncryptedKeyToServer () { // the next line is almost certainly part of the problem // but I don't know how to fix!!! AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build(); AESCipherService cipherService = component.provideCipherService(); Long sessionID = cipherService.getSessionId(); Log.d(Constants.TAG, "singleton verification: " + (Long.toString(sessionID))); }
这是一些示例输出:
会议ID:217186720
单身验证:790090968显然,我没有访问同一个对象。 我意识到至少部分问题源于我在尝试获取
AppComponent
类的引用时在AESCipherService
调用new
运算符的方式,但我不知道如何获取此引用另一种方式。我该如何解决? 谢谢!
I've been working to understand and set up Dagger to handle dependency injections for my Android project. My single (no pun intended) objective is to create singleton objects that I can access across my application. I have successfully set up the objects in the initial activity. Where I am stuck is in accessing those objects from other classes. Here is my setup thus far:
Initial App Activity
public class SplashScreenActivity extends AppCompatActivity { @Inject SessionKeyExchangerService exchangerService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash_screen); AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build(); // establish the session id as a singleton object exchangerService = component.provideSessionKeyExchangerService(); // test whether I can access the singleton from another class exchangerService.sendEncryptedKeyToServer(); }
Component Class
@Singleton @Component(modules = {AppModule.class}) public interface AppComponent { SessionKeyExchangerService provideSessionKeyExchangerService(); AESCipherService provideCipherService(); }
Module Class
@Module public class AppModule { @Provides @Singleton AESCipherService provideCipherService() { return new AESCipherService(); } @Provides @Singleton SessionKeyExchangerService provideSessionKeyExchangerService(AESCipherService service) { return new SessionKeyExchangerService(service); } }
AESCipherService
public class AESCipherService { private Long sessionId; public AESCipherService() { sessionId = makeSessionId(); Log.d(Constants.TAG, "Session ID: " + Long.toString(sessionId)); } private Long makeSessionId() { // this generates a random unsigned integer in the space {0, 2^32-1) Random random = new Random(); return random.nextLong() & 0xffffffffL; } public Long getSessionId() { return sessionId; } }
SessionKeyExchanger Class
public class SessionKeyExchangerService { private static SessionKeyExchangerService exchanger; private AESCipherService cipherService; @Inject public SessionKeyExchangerService(AESCipherService cipherService) { this.cipherService = cipherService; } public void sendEncryptedKeyToServer () { // the next line is almost certainly part of the problem // but I don't know how to fix!!! AppComponent component = DaggerAppComponent.builder().appModule(new AppModule()).build(); AESCipherService cipherService = component.provideCipherService(); Long sessionID = cipherService.getSessionId(); Log.d(Constants.TAG, "singleton verification: " + (Long.toString(sessionID))); }
Here is some sample output:
Session ID: 217186720
singleton verification: 790090968Clearly I'm not accessing the same object. I realize that at least part of the part of the issue stems from the way that I call the
new
operator in theAESCipherService
when I am attempting to get a reference to theAppComponent
class, but I don't know how to get this reference any other way.How do I fix this? Thanks!
原文:https://stackoverflow.com/questions/32211930
最满意答案
重写类(控制器也是类!)将为新类提供基类所具有的所有未来(除了直接访问私有方法或属性)。 但是不要忘记,基类仍然可以在新类旁边使用。 它依赖于你实例化的类。
$a = new BaseClass();
VS
$a = new NewClass();
那么问题是Symfony会使用哪一个? 这就是你可以通过路由管理的东西。 只要在你的app / config / routing.yml中:
fos_user: resource: "@FOSUserBundle/Resources/config/routing/all.xml"
Symfony将使用原始的FOSUserBundle控制器。 只需在vendor / FOS ..目录中找到这些xml文件,然后将它们复制到您自己的项目中。 上面的更改显示规则到您自己的包并更改xml文件中的控制器名称。 当然你也可以编写自己的.yml文件。
Overriding Classes (Controllers are classes too!) will give the new class all the futures that the base-class has (except direct access to private methods or properties). But do not forget that the base-class still can be used beside the new class. It dependence's which class you instantiate.
$a = new BaseClass();
vs
$a = new NewClass();
So the question is which one will Symfony use? And THAT is what you can manage with the routing. as long this is in your app/config/routing.yml:
fos_user: resource: "@FOSUserBundle/Resources/config/routing/all.xml"
Symfony will use the original FOSUserBundle controllers. Just find those xml files in the vendor/FOS.. directory and copy them to your own project. Change above showed rule to your own bundle and change the controllernames in the xml files. Of course you could write your own .yml files too.
相关问答
更多-
我认为拉蒙是对的。 你已经有了用户对象。 在Symfony> 2.1.x中也可以使用 $this->getUser(); 在控制器内部。 I think Ramon is right. You already have the user object. Also in Symfony > 2.1.x you can use $this->getUser(); inside the controller.
-
在特定情况下,FOSUserBundle不会覆盖twig模板(FOSUserBundle not overriding twig template in specific cases)[2022-04-08]
这可能是区分大小写的问题。 将其更改为/app/Resources/FOSUserBundle/views/Security/login.html.twig (小写s - >大写S )。 然后通过ls -l检查(如果相关,还要检查您的版本控制)。 It may be a problem with a case sensitivity. Change it to /app/Resources/FOSUserBundle/views/Security/login.html.twig (lower case s ... -
您可以按字段呈现表单字段,如下所示: {{ form_label(form.username) }} {{ form_widget(form.username) }} {{ form_errors(form.username) }} {{ form_label(form.email) }} {{ form_widget(form.email) }} {{ form_errors(form.email) }} {{ form_label(form.plainPassword.first) }} {{ fo ...
-
我解决了我的问题:我只是导入了我在配置文件app \ config \ config.yml中创建的新服务 imports: - { resource: @UaeUserBundle/Resources/config/services.yml } i solved my problem: i just imported the new service that i created in the config file app\config\config.yml imports: - { r ...
-
问题主要与Symfony2或FOSUserBundle无关,而是与PHP缓存文件统计信息的方式有关。 要找到要加载的正确模板,标准Symfony2使用Symfony\Component\HttpKernel\Kernel->locateResource ,首先检查.app\Resources目录中是否存在覆盖,如果$first参数设置为true,则从内部返回foreach循环。 在我的配置中,PHP决定继续使用filecache并对file_exists回答no,即使文件在那里也是如此。 为了解决这个问题, ...
-
Symfony2重写控制器(Symfony2 Overriding Controllers)[2022-07-06]
花了好几个小时试图让这个工作,并最终弄明白了。 我缺少的部分是使用MyUserBundle中的User实体扩展我的User类。 例如: namespace MyNamespace\MyMainBundle\Entity; use MyNamespace\MyUserBundle\Entity\User as BaseUser; class User extends BaseUser { } User实体与FOSUserBundle中的实体相同(只是具有不同的命名空间)。 namespace MyNam ... -
Symfony 2 - FOSUserBundle - 添加的字段不会以表单形式出现(Symfony 2 - FOSUserBundle - Added field doesn't appear in form)[2022-03-25]
在应用程序配置文件中,试试这个: fos_user: db_driver: orm # other valid values are 'mongodb' and 'couchdb' firewall_name: main user_class: AppBundle\Entity\User registration: form: type: AppBundle\Form\RegistrationType confirmat ... -
重写类(控制器也是类!)将为新类提供基类所具有的所有未来(除了直接访问私有方法或属性)。 但是不要忘记,基类仍然可以在新类旁边使用。 它依赖于你实例化的类。 $a = new BaseClass(); VS $a = new NewClass(); 那么问题是Symfony会使用哪一个? 这就是你可以通过路由管理的东西。 只要在你的app / config / routing.yml中: fos_user: resource: "@FOSUserBundle/Resources/config/r ...
-
我安装并配置了Symfony 3.4的最新副本以及最新的FOSUserBundle 2.1 由于bundle继承正在消失,只需调整寄存器路由指向你的控制器: # config/routes.yaml fos_user: resource: "@FOSUserBundle/Resources/config/routing/all.xml" fos_user_registration_register: path: /register controller: AppBundle\Con ...
-
您在extends有错误的字符串。 更改 {% extends AppBundle::base.html.twig %} 至 {% extends '::base.html.twig' %} 它应该工作。 注意:使用::base.html意味着模板引擎将在app/Resources/views/base.html.twig查找app/Resources/views/base.html.twig 。 设置AppBundle::base.html.twig是错误的。 如果模板位于一个包中(即AppBundl ...