我有一个小小的两难问题,涉及到Guice和避免非Guice单例。考虑一个多模块项目,其中有3个模块:共享
、前端
和后端
。前端
和后端
都使用共享
模块内的配置文件
类的实例(该模块是times方法,并在整个项目中广泛使用)。
几乎每个类都需要使用这个profiling
实例(包括在用户连接时动态创建的user
对象)。
如果每个类都需要profiling
类的一个实例,那么不同的方法都有缺点:
private final Profiling profiling;
@Inject
public User(Profiling profiling, String username)
解决方案2(仅作为实例字段):
@Inject
private Profiling profiling;
public User(String username)
缺点:与上面类似,您必须使用Guice的injector
来实例化每个对象。这意味着要动态创建user
对象,您需要在创建user
对象的类中有一个注入器的实例。
解决方案3(作为一个(主)类中的静态字段,由我们手动创建)
public static final Profiling PROFILING; // Can also use a get method
public Application() {
Application.PROFILING = injector.getInstance(Profiling.class)
}
@Inject
private static Profiling profiling;
// You need to request every single class:
// requestStaticInjection(XXXX.class)
谢谢!
从实际意义上讲,我会使用一个普通的单例,也许是通过一个单字段枚举或类似的模式。
要了解原因,您应该问一个问题:Guice和依赖注入的目的是什么?其目的是将应用程序的各个部分解耦,以便它们能够独立开发和测试,并集中配置和重新排列。考虑到这一点,您需要权衡耦合的成本和解耦的成本。这取决于您选择耦合或解耦的对象。
在这里,耦合的代价是,如果没有一个真实的分析实例,就无法操作应用程序的任何部分,包括在测试中,包括像User这样的模型对象。因此,如果分析对其环境做出任何假设(例如,高分辨率系统定时调用的可用性),那么如果不允许禁用分析,您将无法使用像User这样的类。此外,如果您希望您的测试通过一个新的(非单例)分析实例进行分析,以实现测试隔离,那么您将需要单独实现它。但是,如果您的分析类足够轻量级,不会造成巨大的负担,那么您可能仍然会选择这种方式。
// Nested interface for your Factory:
public interface Factory { User get(String username); }
// Mark fields that the user provides:
@Inject public User(Profiling profiling, @Assisted String username) { ... }
// Wire up your Factory in a Module's configure:
install(new FactoryModuleBuilder().implement(User.Factory.class));
// Now you can create new Users on the fly:
@Inject User.Factory userFactory;
User myNewUser = userFactory.get("timothy");
解决方案3,请求静态注入主持有者近似于我的想法:对于不是通过依赖注入创建的对象,请求静态注入单个类,如profilingholder
或其他类。为了灵活起见,您甚至可以赋予它no-op行为:
public class ProfilingHolder {
// Populate with requestStaticInjection(ProfilingHolder.class).
@Inject static Profiling profilingInstance;
private ProfilingHolder() { /* static access only */ }
public static Profiling getInstance() {
if (profilingInstance == null) {
// Run without profiling in isolation and tests.
return new NoOpProfilingInstance();
}
return profilingInstance;
}
}
当然,如果您依赖于对VM单例的调用,那么您实际上是在接受一个普通的VM全局静态单例模式,只是在可能的情况下使用了Guice。您可以很容易地改变这种模式,使Guice模块bind(Profiling.class).toInstance(Profiling.instance);
获得相同的效果(假设可以在没有Guice的情况下实例化分析)。
解决方案4,每个类的requestStaticInjection是唯一我不会考虑的。类的列表太长,而且它们改变profiling
的可能性太小。您会将一个模块变成一个高维护成本的杂货店列表,而不是任何有价值的配置,您会强迫自己破坏封装或使用Guice进行测试。
问题内容: 首先一些背景: 我正在研究一些基于Apache Sling的 webapp原型代码,该代码基于OSGI并在Apache Felix上运行。尽管我认为到目前为止我已经掌握了大多数概念,但我对OSGI还是比较陌生。但是,令我感到困惑的是,我找不到一个“完整的”依赖项注入(DI)框架。我已经使用声明式服务(DS)成功地使用了基本的DI。但是我的理解是DS可以用作参考- 我该如何处理?-OSG
问题内容: 当前在app.js中,我有以下路线: 如您所见,我正在尝试注入Path依赖项。尽管我收到一条错误消息,说找不到该提供程序。我认为这是因为配置模块提供程序首先执行。以下是“ services.js”中我的路径提供程序定义 我怎样才能将此提供程序注入配置模块? 问题答案: 在中,只能使用提供程序(例如)。在你只能使用服务(如实例)。您有一家工厂,而不是供应商。请参阅具有以下三种创建方式的代
让我们创建一个名为的新模块,并在那里定义CounterService。 app/shared/shared.module.ts 现在我们将引入 SharedModule 到AppModule 和中。 app/lazy/lazy.module.ts 使用此配置,两个模块的组件都可以访问CounterService。 我们将以完全相同的方式在EagerComponent和LazyComponent中使
我需要ASP。Net核心依赖注入,将一些参数传递给实现ICardPaymentRepository接口的GlobalRepositoryClass的构造函数。 参数是用于配置的,来自配置文件和数据库,我不希望我的类去引用数据库和配置本身。 我认为工厂模式是实现这一点的最佳方式,但我想不出使用工厂类的最佳方式。工厂类本身依赖于配置和数据库。 我的创业公司目前看起来像这样: GlobalReposit
问题内容: 在我的NestJS应用程序中- 我有TypeScript类,这些类中已经注入了其他类和值。唯一的是,我要导入带有语句的TypeScript类,并使用DI系统注入它们。有什么方法可以删除导入语句并让DI系统处理它? 问题答案: TL; DR ->类参考 DI->类实例化 可以通过字符串标记进行匹配,但最好使用类引用。 封装形式 依赖项注入系统主要处理类的实例化。这很好,因为您不必关心要注
我想在使用guice实例化子类时,将依赖项注入父类。在下面的示例中,我试图创建的一个实例,同时希望能够在运行时使用Guice注入。我该怎么做?