I am new to nodejs and typescript, coming from C#.
I want to use dependency injection in my project and found that the most popular package is inversify.
I started using it but I don't like the fact that I have to add decorators all over.
for example it bothers me that I need to add #inject before parameters in the constructor:
public constructor(
#inject(TYPES.Weapon) katana: Weapon,
#inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon
)
This mean every class has to know the TYPES object...
I don't understand why #inject needs the string literal and can't inject just on the basis of the type...
Is there a neater way to do this?
In contrast to strictly typed languages, TypeScript types don't exist at runtime. It's possible to use type information at runtime for dependency injection but in limited ways. With the use of emitDecoratorMetadata TypeScript option it's possible to get constructor parameter types and use them for DI.
The example is injection-js, which is Angular injector that was extracted from the library for standalone use. Only #Injectable decorator is needed to be used on DI-enabled class, #Inject parameter decorators are optional.
The limitations are that only class instances can be injected this way:
constructor(foo: FooClass) {}
Generics are ignored and discarded:
constructor(foo: FooClass<Bar>) {}
Other types are ignored and result in DI error:
constructor(foo: fooSymbol) {}
constructor(foo: 'foo string provider') {}
The same applies to InversifyJS:
In case of concrete injections, you can simply define your constructor
parameters as usual without using the #inject decorator.
InversifyJS also supports TypeScript's constructor assignments so you
can have private or protected access modifiers in your parameters and
the container will have no trouble injecting the dependencies
It would be possible to omit #inject for Weapon and ThrowableWeapon if they were classes but in listed example TYPES.Weapon is a symbol and Weapon is an interface that doesn't exist at runtime, so #inject is necessary.
Related
With current spec (2.0) there is no way to prevent class explosion
problem like what we do with decorator pattern:
Cake cakeWithToppings = new ColoredSprinklesDecorator(new ShavedChocolateDecorator(new ToastedCoconutDecorator(new BaseCake())));
cakeWithToppings.delish();
Now to do that with CDI our options are create all possible combinations
of cake toppings(2^3 = 8) as class or with producer method with qualifiers which
will create problem of qualifier and producer method explosion.
When GoF decorator used there is need for only 5 classes Cake, CakeDecorator, ColoredSprinklesDecorator, ShavedChocolateDecorator, ToastedCoconutDecorator, BaseCake.
And #Decorator doesn't solve this issue as i can see.
Is there any way I couldn’t think of or is cake lie?
I am not sure I fully grasp your point, but I'll give it a go...
I think you are mixing two things here - GoF's decorator pattern and CDI's decorator which is not quite an implementation of that pattern.
In CDI, #Decorator can be seen as a "semantics-aware" interceptor rather than implementation of GoF's Decorator pattern.
This means that it can wrap calls to underlying beans of given types while being able to leverage the semantics.
E.g. you can create a decorator which will wrap all calls to any Cake:
#Decorator
#Priority(1)
public class CakeDecorator implements Cake {
#Inject
#Delegate
Cake cake; // this will cause to it decorate all cakes
public void delish() {
// do stuff BEFORE actual cake's delish() invocation
addMoreChocolate(cake);
cake.delish(); // this is the original method invocation
// do stuff AFTER actual cake's delish() invocation
cleanUp(cake);
}
}
But you can also easily modify the decorator to trigger for only certain types of cakes - you can do that by either changing the delegate injection point, or simply by checking cake type withing the method body. You can also chain several decorators if you so wish.
I'd say CDI's decorator is meant to meet slightly different goals. You could in fact design a decorator accordingly to GoF's principles and then apply CDI's decorator on top of that.
I often find huge list of #Inject fields at the beginning of a class. This is a lot of redundant repetitions of the #Inject annotation.
Using some custom annotation magic, is it possible to write a new #InjectAll annotation to enable this simplification in code:
before, annotating individually each field:
#Inject
private Logger logger;
#Inject
private Event<String> simpleMessageEvent;
after, grouping all injected fields in one group:
#InjectAll {
private Logger logger;
private Event<String> simpleMessageEvent;
}
or any equivalent syntax which allows me to write more compact code?
Your proposal includes two Java syntax errors:
You can't group field declarations in a block.
You can't annotate blocks.
You might be able to create a CDI extension to support something like
#InjectAll({"logger", "simpleMessageEvent"})
public class MyClass {
private Logger logger;
private Event<String> simpleMessageEvent;
}
but this is not really less verbose than having the #Inject annotation directly on the fields.
In CDI there is no built-in way to achieve this.
As was mentioned, you can use CDI extension combined with your imagination to create a custom syntax which will do just what you want. However, this will not make things much simpler and might just add on to complexity and lessen readability of code.
I'd rather suggest you go through your code again and see if you truly need that many injections in each class or if, perhaps, you need to refactor that class into several others to divide the per-class responsibility evenly. What you describe is often a case of "uber entry classes" which handle pretty much everything - that, of course, is not the best of practices.
What is the purpose of runtime mixins in groovy?
Mixins overall one of the ways to add functionallity to class without multiple inheritance issues. But what is its purpose in Groovy? Traits can do the same.
Annotation #Mixin is considered deprecated at all. Will runtime mixins have the same fate one day?
Runtime mixins give us the ability to add methods to existed classes at runtime. The important part of the answer is "existed" and "runtime".
So, you can easily add new methods to any 3rd party library at runtime.
Actually, recently I found a case where using mixins helped me a lot.
String.metaClass {
invokeMethod {
String name, args ->
System.out.println "[$name] invokation with $args"
}
}
class GroovyInterceptableWrapper
implements GroovyInterceptable {
}
String.mixin(GroovyInterceptableWrapper)
Though again if I used there trait instead of class and then invoked withTraits I would have achieved the same result.
I am writing junit test to test BaseClass method. The method uses super class members.
The BaseClass constructor invokes super(arg1, arg2).
In the super(arg1, arg2) constructor there is a dependency injector setting a private member
of the super class.
When I am running the test, since the dependency is not set, the super() is throwing an
exception. I want to mock only that statement in the super() which is setting the private member with dependency injection. How to do with mockito ?
Field injection is always a problem for testing. So whenever you have the choice, choose constructor injection instead.
You could start the dependency injector and make it inject a mock instead of a real class. Solutions would depend on the DI framework that you use actually (guice, cdi, ...) For guice you could use jukito, for cdi Arquillian for example. But it slows down the test execution and adds complexity to your test class.
As a alternative you could reflect the private field on an instance of you test class an simply set a mock. Something like:
instance = new TestObject();
Field injected = TestObject.class.getDeclaredField("injected");
injected.setAccessible(true);
injected.set(instance, mock(InjectedType.class));
while TestObject is the class that you want to test, injected the private field where something is injected an InjectedType the type of that private field.
I am very new to concept of IOC and I understand the fact that they help us resolve different classes in different contexts. Your calling class will just interact with Interface and Interface with decide which implementation to give you and it takes care of newing up the object.
Please do correct me if I am understanding is wrong because my question is based on that:
Now, I see this pattern very often in these projects:
private readonly IEmailService emailService;
private readonly ITemplateRenderer templateRenderer;
private readonly IHtmlToTextTransformer htmlToTextTransformer;
public TemplateEmailService(IEmailService emailService,
ITemplateRenderer templateRenderer,
IHtmlToTextTransformer htmlToTextTransformer)
{
this.emailService = emailService;
this.htmlToTextTransformer = htmlToTextTransformer;
this.templateRenderer = templateRenderer;
}
I understand that this helps using all the implementations of these classes without newing them up and also you don't have to decide WHICH implementaion to get, your IOC decides it for you, right?
but when I code like this, I do not even touch any IOC congiguration files. And again I am usin git for 2 days only but from all the tutorials that I have read, I was expecting my self to configure something which says "Resolve IParent to Child" class. But it works without me doing anything like it. Is it because there is only one implementaion of these interfaces? and If I do have more than one implementations then and then only I will have to configure resolved explicitly?
The code sample you have is a case of Constructor Injection.
In a traditional code, you would have a parameterless constructor, and in it you would "new-up" your objects like this:
IEmailService emailService = new EmailService();
So your code is explictly controlling which implementation gets assigned to the interface variable.
In IoC using constructor injection, control is inverted, meaning the container is "driving the bus" and is creating your TemplateEmailService object. When it is about to create it, the container looks at your constructor parameters (IEmailService , ITemplateRenderer , etc.) and feeds those objects to your class for use.
The IoC container can be configured so that interface A gets fulfilled by implementation B (or C) explicitly. Each one has a way to do it. Or it could do it by convention (IFoo fulfilled by Foo), or even attributes in classes, whatever.
So to answer your question-- you can explicitly define which implementations get used to fulfill certain interfaces. Got to read the IoC container docs for how to.
One more thing - "when you code like this", you technically don't have to be using an IoC container. In fact, your class should not have a direct reference to the container - it will maximize the reusability, and also allow easy testing. So you would wire-up interfaces to implementation classes elsewhere.