The task is to hide Library1 interface1 behind the facade of Library2.
Full source here https://bitbucket.org/tim4dev/inheritance-interfaces/src/master/
(Library1) interface1
(Library2) interface2 : interface1
(Library2) Klass2: Interface2
(application)
implementation project(":library2")
class KlassApp constructor(
private val klass: Interface2
) {
fun klassAppFun() {
klass.interface1fun1()
}
}
We get an error
KlassApp.kt: Unresolved reference: interface1fun1
Question: what are the standard patterns to hide Library1 behind the facade of Library2 ?
You need to choose:
make Library1 an api dependency of Library2, not implementation as you currently have it (so not hide it fully);
if you want to hide it, you can't expose any types of Library1 in public parts of Library2, which includes extending its interfaces.
See the documentation for the difference of api and implementation:
So when should you use the api configuration? An API dependency is one that contains at least one type that is exposed in the library binary interface, often referred to as its ABI (Application Binary Interface). This includes, but is not limited to:
types used in super classes or interfaces
types used in public method parameters, including generic parameter types (where public is something that is visible to compilers. I.e. , public, protected and package private members in the Java world)
types used in public fields
public annotation types
Related
What is the difference between sealed and internal in Kotlin? I have read Kotlin's documentation on sealed classes and visibility modifiers; however, it is still not clear to me when to use sealed vs. internal. Maybe someone could provide real-world code samples?
Sealed classes | Kotlin & Visibility modifiers | Kotlin resources.
sealed class will be visible in all modules, but extendable only in the same module. This means if you have this:
sealed class MyClass {} then you can do this in the same module:
class MyExtensionClass: MyClass() {}
But you can't do the same thing in another module. But you can still use both MyClass and MyExtensionClass in another module.
For example you can do this in another module:
val x: MyClass = MyExtensionClass()
You can't instantiate a sealed class directly neither in the same or another module. This means you can't do this nowhere:
val x = MyClass()
So sealed class is basically an abstract class which can only be implemented in the same module.
internal class can be used and extended in the same module just like a sealed class, but you can do neither in another module. So you can't even use or instantiate it in another module. Also you can directly instantiate an internal class as long as you are doing it in the same module.
So: Use sealed to better control extending something. For example you create a library and you want a class from this library to be used but not extended. Use internal if you wan't your class to be invisible to other modules (you create a library, but certain class in this library shouldn't even be directly compile time usable by libraries users)
A good use case for sealed class:
You build a library and have some abstract class or interface which has multiple different implementations, but you want to make sure the libraries user doesn't add its own implementations (you wan't to be in control of implementation details).
A good use case for internal class:
You have some interface and a factory that creates implementations, but you don't want the implementing class to be compile-time visible to libraries users. They just use the factory and don't need to worry about the implementation. They might build their own implementation though and therefor not use the factory you provided and this is OK.
These are not mutually exclusive. You can have an internal sealed class as well.
internal is about visibility, and sealed is about inheritance rules.
internal means the class type is only visible within the module. In other modules, you can't even mention the name of the type.
sealed means it is open (can be subclassed), but subclasses (or implementations if it's a sealed interface) can only be defined in the same module, and the compiler keeps track of an exhaustive list of all subclasses. Another rule is that you can't create anonymous subclasses of it (object: MySealedClass). The advantage of a sealed type is that the compiler knows when you've exhaustively checked a type in when statements, if/else chains, etc. It can also be used in a library to ensure that only known implementations of a class or interface are ever passed to it (prevent users from creating subclasses of something and passing them into the library).
Bonus:
Visibility modifier keywords: public, internal, private, protected
Inheritance modifier keywords: open, final, sealed
data and value also cause a class to be final implicitly as a side effect.
I have two different #Service classes that use the same methods.
I have extracted those methods in a separate class, that both will reference. To be able to access those methods, I added them to the companion object of the class, but the issue is that they use external services in their implementation, which I cannot wire in a companion object or pass it and access it there.
class CommonMethods {
companion object {
fun firstValidationField(input: User) {
// logic
input.timezone = userRepository.getTimezone(input.userId)
return input
}
etc
}
}
What is the best way to inject userRepository to this class so I can access it and have the common methods work for both external service classes?
I had these methods in the service class, so autowiring repositories there wasn't an issue. But extracting them as they are common, not sure how to approach this.
I use #Autowired to inject it
If firstValidationField() is really so simple as you wrote in the question, you can inject the userRepository in your both services, and userRepo.getTimeZone(..) that's it.
However, if the method impl. is more complex than that, or there are other commonly used methods, I would suggest wrapping those methods in an additional #service, say UserService, and inject the UserService into your other #services.
Usually, Util classes are not designed to be instantiated, it contains mainly static method calls. IMO, "Injecting" objects to a Util class isn't the right direction to go.
I've read what the annotation says but I'm kinda dumb, so couldn't understand propertly
Identifies injectable constructors, methods, and fields. May apply to static as well as instance members. An injectable member may have any access modifier (private, package-private, protected, public). Constructors are injected first, followed by fields, and then methods. Fields and methods in superclasses are injected before those in subclasses. Ordering of injection among fields and among methods in the same class is not specified.
Can you explain me what is #Inject for? If it is possible with a real life analogy with something less abstract
#Inject is a Java annotation for describing the dependencies of a class that is part of Java EE (now called Jakarta EE). It is part of CDI (Contexts and Dependency Injection) which is a standard dependency injection framework included in Java EE 6 and higher.
The most notorious feature of CDI is that it allows you to inject dependencies in client classes. What do I mean by dependencies? It is basically what your class needs to do whatever it needs to do.
Let me give you an example so that it is easier to understand. Imagine that you have a class NotificationService that is supposed to send notifications to people in different formats (in this case, email and sms). For this, you would most probably like to delegate the actual act of sending the notifications to specialized classes capable of handling each format (let's assume EmailSender and SmsSender). What #Inject allows you to do is to define injection points in the NotificationService class. In the example below, #Inject instructs CDI to inject an EmailSender and SmsSender implementation objects via the constructor.
public class NotificationService {
private EmailSender emailSender;
private SmsSender smsSender;
#Inject
public NotificationService(EmailSender emailSender, SmsSender smsSender) {
this.emailSender = emailSender;
this.smsSender = smsSender;
}
}
It is also possible to inject an instance of a class in fields (field injection) and setters (setter injection), not only as depicted above in constructors.
One of the most famous JVM frameworks taking advantage of this dependency injection concept is Spring.
I have a class whose declaration is like :
class NetworkManagerImpl : NetworkManager { }
I wanted to make the class protected so that it is visible inside package only. But when i add protected in front of class like :
protected class NetworkManagerImpl : NetworkManager { }
It gives error as Modifier protected is not applicable inside file
How to fix this error or more importantly how to make an entire class(Top level) protected?
As written in the docs, there is no protected modifier for top-level entities like classes.
Here’s a statement coming from a Kotlin team member:
The motivation for not having package protected access is very simple: it does not provide any real encapsulation. Any other module in the system can define classes in the same package as your complex independent component and get full access to its internals. On the other hand, classes with internal visibility cannot be accessed from any module other than the one where they are defined.
We are implementing IoC/DI in our application using NInject framework. We are having internal classes having internal methods. To implement IoC/DI, we have to extract interfaces. But if we are having only internal methods in an internal class, we can't extract interface for that class.
So is there a way to implement IoC/DI in such cases (internal class having only internal methods) or should we change our internal methods to public methods. Kindly suggest. Thanks
If your class is already internal then there is absolutely not difference between internal and public methods. public methods of internal classes are only internally visible.
If you stay with injecting concrete classes though you loose all the advantages of DI. So yes you should extract (internal) interfaces and inject the interfaces. This requires that the configuration code has access to the classes by either beeing in the same assembly of the assembly must be declased as friend assembly. Futhermore, you have to configure Ninject to allow none public classes. See NinjectSettings.
The only thing that you really need to make public is the interface (not the concrete implementation).
You can use an abstract factory or (easier) Ninject to map the public interface to the internal concrete; thus your client code just has to request an instance of "a thing" that implements the interface and your factory / container will return the implementation.
You should read up on Dependency Inversion Principle as well as it goes hand-in-hand with this.
You could use InternalsVisibleTo attribute in AssemblyInfo.cs file like this
[assembly: InternalsVisibleTo("Assembly_That_Should_Access_The_Internal_Class")]