Typhoon: how to inject class instead of instance - swift

I have a third-party library which is written in Swift. The library provides a class that has some class methods in it. Using Typhoon, I want to inject the class into one of my classes so that, under unit testing, I could inject a mock class that provides fake class methods. I'm new to Typhoon and I went though the documentation, but haven't figured out how to do it. Is this even doable with Typhoon?

Yes, in the User Guide the section on Injecting Configuration shows how to inject primitives, scalar values and so forth.
To inject a class:
[initializer injectParameterWith:[SomeClass class]];
This also applies to property injection and method injection.
To inject a selector:
[initializer injectParameterWith:NSValueFromPrimitive(#selector(selectorValue))];
Typhoon rules:
References to other definitions are resolved to the built instance.
Simple objects, primitives and scalar values are injected as-is (scalar values and primitives must be wrapped).
Collections (NSArray, NSSet, etc) that contain references to other definitions have those references resolved to the built instance. Any other values pass through as is.
There is also Typhoon Config, which allows storing configuration, simple objects and so forth in an external plist, json or properties file.

Related

How are Classes an Annotations Related in Java?

I found this quote
the first step to using reflection is to obtain a Class object that
represents the class whose annotations you want to obtain
from Herbert Schildt
Can anyone explain that sentence and also "Class" with respect to annotations. Does an annotation reside inside a "Class" or not?
You can add annotations to lots of symbols like classes, methods, constructors etc.
The point of the quote is, that in order to access those annotations at run-time, your entry point is the class object. From there you can start inspecting it, looking for methods, members etc. and access their annotations. This API is also called reflection, because it essentially reflects the code you have written as an object at run-time (including annotations).

Dagger 2 - Proper way to provide instances within a very own module only

Say I have something like this:
#Module
internal class SeenModule {
#Provides
fun parameter() = Parameter()
#Provides
fun actualThingINeedToInject(parameter: Parameter) = ActualThing(parameter)
}
However, this module only really needs to provide an ActualThing object - in other words, the Parameter is only there because the very own module needs it. I don't want it to be part of the set of dependencies that can be retrieved outside of this module.
The way I'm currently doing this is by defining a custom scope as private and then marking the methods that provide dependencies which shouldn't leave the module with this scope, as well as those in the module where the provided dependencies should be injected, of course. This is a bit annoying because it prevents me from using other scopes in these methods and requires a lot of additional annotating all over the place. What is the proper way to achieve this?
Dagger doesn't really offer "private bindings" in the sense you're asking for, where Parameter would not be injectable from anywhere else. I also advise against using scope annotations for visibility, in part because the Component itself would need to be annotated with that scope annotation, so the scope annotation would simply slightly increase the hassle needed to improperly consume Parameter (and the hassle needed to create a Component that properly consumes Parameter).
I'd offer one of these three alternatives:
Reduce the visibility of Parameter as a class. If Parameter is package-private, you won't be able to refer to it from outside of that Java package, giving you the encapsulation you want.
Use "Subcomponents for Encapsulation", in which you create a subcomponent, install your Parameter (and any related bindings) in a Module bound on the subcomponent, and expose only your ActualThing on the subcomponent's interface. Your subcomponent will be injectable, but your Parameter is not; you can also write a #Provides method that returns your ActualThing from your subcomponent instance.
Grin and bear it, and just document that Parameter is an implementation detail that should not be accessed outside of certain packages. If you are providing objects to external teams who access ActualThing through your Component interface, you can simply decline to put Parameter on your public interface; if you are providing objects to internal teams they will likely have access to change your Dagger structure or access modifiers anyway. You might also ask yourself why Parameter would be useful for another team to consume, and document it as an API if there is a business reason for injecting it.

Play framework controller test - No implementation for <classname> was bound

I would like to write test for a controller class. The controller class takes a service object as constructor parameter. Added the #Inject annotation to the constructor of the service class.
class AssociateService #Inject()(configuration: Configuation){...}
The constructor parameter of the service class is a custom configuration object also created for the application. I added the #Inject to the constructor of the config class as well. Now I'm getting these types of error messages:
No implementation for "className" was bound.
Could not find a suitable constructor in java.lang.Integer. Classes must have either one (and only one) constructor annotated with #Inject or a zero-argument constructor that is not private.
The configuration class has several constructor parameters, those are "basic" types (Int, Boolean) and one parameter is a custom class type (className).
How should I do this binding or is it just enough to annotate something else?
And why it says that constructor error message?
As far as I know, there are two ways with tests and guice, with trade offs:
Don't using field injections, using only constructor injections and fields assignment in constructor for injected parameters. This approach enables very simple solution for testing, just don't use dependency injection in tests. But all your classes must have ability to be created with new operator in test cases...
Ps. You can define optional constructor and use field injections, of course, but it is not very clear solution.
Creating correct module with injectable interfaces binding to its implementations for every test or group of similar tests. Sometimes this approach takes a lot of unnecessary working hours.
You must design your software to maintain testability. Sometimes not every line of code in project need to be tested, sometimes not every code is testable, you must separate it from important parts of your software, that requires testing. If you design your software with single responsibility principe so writing tests is much easer...

Simple container bindings in Swift?

Disclaimer: I'm still learning Swift so forgive me if I haven't understood certain concepts/capabilities/limitations of Swift.
With the Swinject framework, if you wanted to bind a protocol to a class - it seems you have to return the class instance in a closure such as:
container.register(Animal.self) { _ in Cat() }
Is is possible to be able to instead pass in two types to the register() method and have the framework instantiate the class for you? It would need to recursively see if that class had any initializer dependencies of course (Inversion of Control).
This is possible in the PHP world as you have the concept of reflection, which allows you to get the class types of the dependencies, allowing you instantiate them on the fly. I wonder if Swift has this capability?
It would be much nicer to write this:
container.register(Animal.self, Cat.self)
This would also allow you to resolve any class from the container and have it's dependencies resolved also (without manually registering the class):
container.resolve(NotRegisteredClass.self)
Note: This only makes sense for classes that do not take scalar types as a dependency (as they need to be explicitly given of course).
The second case - resolving a type without the explicit registration - is currently not possible because of Swift's very limited support for the reflection.
However, there is a SwinjectAutoregistration extension which will enable you to write something very close to your first example:
container.autoregister(Animal.self, initializer: Cat.init)

Play Framework dependency injection Object vs #Singleton Class

Play Framework 2.4 has support for Google Guice Dependency Injection
What is the advantage of using
#Singleton class A
instead of
object A
for singletons?
I can see three advantages of using #Singleton class over object if A has no dependencies:
If you wanted to test A, and declare it as #Singleton class you have the option of subclassing it to mock out some of the functions in your test, whereas this is not possible with an object.
If you use object, it is very tempting for clients of A to reference it directly, leading to a strongly coupled system, but using #Singleton class forces them to think about where A is instantiated, probably leading to a more decoupled design.
If you later change your mind, and allow multiple instances of A, the refactoring will be much easier to do if you chose to use #Singleton class.
If A has dependencies, however, using #Singleton class allows them to be dependency injected on construction, whereas with an object this is only possible if you declare the dependencies as mutable (eg: a var with getter/setter methods) .