依赖注入和Java包

依赖注入和Java包,java,dependency-injection,packages,Java,Dependency Injection,Packages,我正在做一个有几个软件包的项目。我所有的类都是根据依赖注入ideias实现的 现在,在我的应用程序中,将有一个地方负责实例化所有对象(实际上我正在为此使用一个IoC容器,但这不重要)——所谓的合成根 现在,问题在于,至少在我的理解中,组合根必须知道系统将使用的所有类。也就是说,所有类都必须标记为public 我可以为每个包定义一个包组合根,然后从系统的组合根调用它们中的每一个,但这似乎不是一个好主意 例如,在C#中,情况并没有那么严重,因为没有包保护的访问修饰符——而是有内部修饰符(可用于当前程

我正在做一个有几个软件包的项目。我所有的类都是根据依赖注入ideias实现的

现在,在我的应用程序中,将有一个地方负责实例化所有对象(实际上我正在为此使用一个IoC容器,但这不重要)——所谓的合成根

现在,问题在于,至少在我的理解中,组合根必须知道系统将使用的所有类。也就是说,所有类都必须标记为public

我可以为每个包定义一个包组合根,然后从系统的组合根调用它们中的每一个,但这似乎不是一个好主意

例如,在C#中,情况并没有那么严重,因为没有包保护的访问修饰符——而是有内部修饰符(可用于当前程序集的所有元素)


你们通常是如何处理这个问题的?

大多数容器通过使用反射来绕过访问限制。然而,这只是一种黑客行为,当重新感染允许您忽略访问修饰符时,它会让您感觉您有一些保护

IMHO,如果您正在访问另一个包中的类,那么您应该清楚这一点,并给它一个适当的访问修饰符

现在,问题在于,至少在我的理解中,组合根必须知道系统将使用的所有类。也就是说,所有类都必须标记为公共类。

你们一般是怎么处理的


通过将所有类标记为
public
。在Java世界中,这并不是一个真正的问题。

在我看来,C#中的情况也一样。如果bean工厂位于包的外部,并且开发人员将一个类设置为内部,那么这是否会拒绝对bean工厂的访问

我把课程公之于众,不用太担心

根据定义,客户端应该使用的接口是公共的。因为它们不直接实例化或使用实现,所以不必担心给它们公共访问权


另一种方法可能是创建一个工厂方法并使其可供bean工厂使用。让它选择使用公共工厂为给定的实现提供哪个实现。

这是一个老问题,但我认为仍然要讨论这个问题非常重要。虽然其他人试图说,公开包类以供编写时使用没有问题,但我完全不同意。包最重要的功能是使用访问修饰符对其他包隐藏详细信息。您可以争论details一词,并说提供其主要功能的包的主类不是包的细节。当您使用多态接口将包与外部世界隔离时,我将回答这个问题,主类也是细节的一部分。当您希望在编译时借助语言特性保护您的软件体系结构不被团队中的其他开发人员违反时,限制对该主类的访问是非常有用的。如果您在Python中没有这样的功能,我为您感到抱歉,但这并不意味着不需要在Java、C#等中使用这样一个强大的功能

假设您有一个使用多态接口与外部世界通信的包,并且它的所有内部类型都是访问受限的。那么,当在所有包中执行组合操作时,如何在组合阶段初始化实现该接口的主类呢?这是主要问题


正如Owned也提到的那样,除了在每个包中定义一个公共编写器之外,没有其他方法可以实现,该编写器实例化和编写所有内部类型,并最终返回一个多态接口类型的对象,该接口将此模块与外部世界隔离。

问题是,如果我不使用DI,我可以保留所有这些类型“周遭的“包保护类…包保护。如果您使用OSGi,您可以更详细地定义此类内容。模块必须明确导出可用的软件包。我想问的是,通过对访问修饰符进行更严格的限定,您真正获得了什么。如果您愿意,您可以将它们保留为私有包,甚至是私有包,并通过反射访问它们。但是,您会发现,将组件公开并直接使用它们更简单、更不容易出错。+1:只有其他包中的类访问需要公开。除非每个类都可以成为一个组件,否则这可能不是必需的。在我看来,将所有类公开并不是最好的主意(也就是说,如果它们不一定要公开的话)。您是否将所有方法、所有字段都标记为公共的?不,我唯一公开的方法是那些实现接口的方法,或者是POJO中的简单getter/setter方法。我不相信拥有
公共
类是一个问题——我不担心我的项目中的另一个开发人员恶意使用我的代码来做其他事情。除了使用访问修饰符之外,还有其他方法可以强制分离关注点、模块化、分层等。与之相比,Python这样的语言没有任何访问修饰符——只有开发人员记录哪些方法是供公众使用的,哪些不是;几乎没有田地。那不是马特b。在C#中,类是内部的。同一程序集中的任何其他类(read、.dll)都可以使用它们。但是,如果你试图建立一个多组件项目,问题仍然是一样的。但是,就像我说的,bean工厂不太可能是同一个组件的一部分。如果bean工厂是包的一部分,Java就不会遇到这个问题。这是同样的问题。(错误地)暗示.NET执行某些mag是不诚实的