Reputation: 105067
I'm doing a project that has a couple of packages. All my classes are implemented according to Dependency Injection ideias.
Now, there will be some place, in my application, that'll have the responsability of instantiating all the objects (actually I'm using an IoC Container for that, but that shouldn't matter) -- the so called Composition Root.
Now, the problem lies in the fact that, at least to my understanding, the composition root will have to know all the classes that'll be used of the system. That is, all the classes will have to be marked as public.
I could define for each package a Package Composition Root and then call each one of them from the system's composition Root but that doesn't seem that great of an idea.
In C#, for example, the situation is not so grave as there is not the package-protected access modifier -- there's internal (accessible for all the elements of the current assembly), instead.
How do you guys generally handle this?
Upvotes: 2
Views: 1938
Reputation: 2056
This is an old question but I think is very important to still talk about that. While other guys try to say there is no problem with making classes of packages public to be accessible for composition, I disagree completely. The most import feature of a package is to hide details from the others using access modifiers. You can argue about the details word and say the main class of a package that provides its main features is not details of the package. I will answer when you use polymorphic interfaces to isolate your package from outside world, that main class is also part of details. Restricting access to that main class is useful when you want to protect your software architecture from being violated by the other developers in you team by the aid of language features at compile time. If you do not have such a feature in Python, I feel sorry for you but it doesn't mean there is no need to use such a great feature in Java, C#, etc.
Suppose you have a package that communicate with the outside world using a polymorphic interface and all of its internal types are access-restricted. So how the main class that implements that interface can be initialized in the composition phase while composition operation is happening out of all packages? This is the main question.
As Devoured also mentioned himself, there is no way except defining a public composer in each package that instantiates and composes all internal types and finally returns an object of the type of the polymorphic interface that isolates this module from the outside world.
Upvotes: 0
Reputation: 308763
It sounds to me like the situation is the same in C#. If the bean factory is outside of a package, and the developer makes a class internal, does that not deny access to the bean factory?
I make the classes public and don't worry so much about it.
The interfaces that clients should be using are public by definition. Since they don't instantiate or use the implementations directly, there's little fear of giving them public access.
An alternative might be to create a factory method and make it available to the bean factory. Let it choose which implementation to provide for a given implementation using the public factory.
Upvotes: 4
Reputation: 139931
Now, the problem lies in the fact that, at least to my understanding, the composition root will have to know all the classes that'll be used of the system. That is, all the classes will have to be marked as public.
...
How do you guys generally handle this?
By marking all of the classes as public
. This isn't really seen as a problem in the Java world.
Upvotes: 3
Reputation: 533510
Most containers get around access restrictions by using reflection. However this is just a hack to make you feel like you have some protection when actually relfection allows you to ignore the access modifiers.
IMHO, if you are accessing a class in another package you should be clear about this and give it an appropriate access modifier.
Upvotes: 4