WebSocket.acceptWithActor and #Inject() in the Actor (Play 2.5) - dependency-injection

WebSocket.acceptWithActor instantiates a new Akka actor without making use of Guice.
With Play 2.4, using the injector for my actor was still possible by importing play.api.Play.current.
Snippet from ReactiveMongo documentation:
import scala.concurrent.Future
import play.api.Play.current // should be deprecated in favor of DI
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json.collection.JSONCollection
object Foo {
lazy val reactiveMongoApi = current.injector.instanceOf[ReactiveMongoApi]
def collection(name: String): Future[JSONCollection] =
reactiveMongoApi.database.map(_.collection[JSONCollection](name))
}
But in Play 2.5, play.api.Play.current is deprecated. How can I still inject ReactiveMongoApi in my actor? What is the recommended way of using an instance of ReactiveMongoApi in my actor?
Here is my code which works with Play 2.4 because my custom actor class ClientActor has access to ReactiveMongoApi through current.injector.instanceOf[ReactiveMongoApi]:
#Singleton
class Application #Inject() (system: ActorSystem) extends Controller {
val midiDiscoveryActor = system.actorOf(MidiDiscoveryActor.props, "midi-discovery-actor")
val midiActor = system.actorOf(MidiActor.props(midiDiscoveryActor), "midi-actor")
def index(page: String) = Action {
Ok(views.html.index(page))
}
def bidirectional = WebSocket.acceptWithActor[JsValue, JsValue] { request => out =>
ClientActor.props(out, midiActor, midiDiscoveryActor)
}
}

I don't think this is possible. Quoting James Roper:
The helpers that Play provides for dependency injecting actors are suited for a limited number of use cases. Though, the helpers are really just very thin wrappers over some common requirements - they're not needed at all. In the case Play's WebSocket actor support, the thing is, generally you want to manually instantiate the actor since you have to somehow pass it the out ActorRef. So, you can either do this using Guice assisted inject, and define a factor interface that takes the out actor ref (and whatever other arguments you want to pass to it), or simply instantiate it manually, passing dependencies from the controller to the actor, for example:
class MyController #Inject() (myDep: MyDep) extends Controller {
def socket = WebSocket.acceptWithActor[String, String] { request => out =>
MyWebSocketActor.props(out, myDep)
}
}

Play 2.5 has built in support for DI.
MidiActor signature needs to be modified as said below.
class MidiActor#Inject() (configuration: Configuration, #Named("midi-discovery-actor") midiDiscoveryActor: ActorRef) extends Actor with InjectedActorSupport{
.......
}
Create new Module and enable in application.conf
play.modules.enabled += MyModule
class MyModule extends AbstractModule with AkkaGuiceSupport {
def configure = {
bindActor[MidiDiscoveryActor]("midi-discovery-actor")
bindActor[MidiActor]("midi-actor")
}
}
Change your controller as below
#Singleton
class Application #Inject() (system: ActorSystem,#Named("midi-actor") midiActor: ActorRef,
#Named("midi-discovery-actor") midiDiscoveryActor: ActorRef) (implicit ec: ExecutionContext) extends Controller {
def index(page: String) = Action {
Ok(views.html.index(page))
}
def bidirectional = WebSocket.acceptWithActor[JsValue, JsValue] { request => out =>
ClientActor.props(out, midiActor, midiDiscoveryActor)
}
}

Related

In NestJS how do I create a new instance of a class and have dependencies injected?

I have a set of classes that deal with processing items that are added into a database table (async_item).
Sometimes this will be started from a controller endpoint and sometimes it will be triggered by something else (such as listening to an SQS endpoint).
The call looks like this:
AsyncItemDispatcherFactory.getAsyncItemDispatcher(this.asyncItemService)
.processItem(createOrFindByExternalIdReturn.asyncItemEntity.id)
The dispatcher class from getAsyncItemDispatcher() then uses a switch statement on the item type to decide which handler to instantiate and pass the item to for processing. These handlers could be quite complex and require many services - here is an example skeleton one:
import { ProjectService } from '../../../admin/project/project.service'
import { VintageService } from '../../../admin/vintage/vintage.service'
import { AsyncItemEntity } from '../../../entity/async-item.entity'
import { AsyncItemService } from '../../async-item.service'
import { IAsyncItemHandler } from './IAsyncItemHandler'
export class RegistryCreditsReceivedHandler implements IAsyncItemHandler {
constructor(
private readonly asyncItemService: AsyncItemService,
private readonly projectService: ProjectService,
private readonly vintageService: VintageService,
) {}
handleItem(asyncItem: AsyncItemEntity): void {
// perform the actions to handle the credits received call
}
}
This depends on 3 services but it could be many more.
This is the switch statement but it currently uses new to instantiate the new class but this obviously doesn't perform any DI:
// pass it to its handler to be processed
switch (asyncItem.type) {
case AsyncItemTypes.REGISTRY_CREDITS_RECEIVED:
new RegistryCreditsReceivedHandler().handleItem(asyncItem)
break
default:
throw new Error(`Unknown async_item.type: ${asyncItem.type} id: ${asyncItem.id}`)
}
How can I use the DI in NestJS to create a new instance of a class and have the dependencies injected?
The alternate is that the dispatcher knows about all the dependencies of each of the handlers, which is likely to become a very large list, which just feels wrong...

How to implement dependency injection in Flutter manually?

Since there is no official library from the flutter team, I'm trying to implement the dependency injection in flutter manually using the singleton pattern, after a long search this is what I came up with:
class Injector{
Injector._internal();
static final _singleton = new Injector._internal();
factory Injector() => _singleton;
SomeClass get someClass => new SomeClass();
}
Now, Injector is singleton that has one instance once instantiated and SomeClass is the dependency I want to inject in my code. The above code works, but the problem is where should I instantiate the Injector class and make it available every where in my code. Do you think Global Variable is good in this situation or is there a better way? Thanks.
To implement your own dependency injection I usually use a combination of
A 'Bindings' class which has getters to all injected services
A static getter/setter which holds a single instances of the Bindings class. This is important for overriding the bindings.
The getters which return classes should lazily construct them if they have dependencies. This allows you to override any parts of your graph by extending the Bindings class and setting it in the global bindings. For example, below I have three classes with the third depending on the first two.
class Foo {}
class Bar {}
class Fizz {
Fizz(this.foo, this.bar);
final Foo foo;
final Bar bar;
}
class Bindings {
/// Can be final since there are no dependencies
final Foo foo = new Foo();
final Bar bar = new Bar();
Fizz _fizz;
Fizz get fizz {
_fizz ??= new Fizz(foo, bar);
return _fizz;
}
}
Bindings get bindings => _bindings;
Bindings _bindings;
set bindings(Bindings value) {
_bindings = value;
}
Now suppose I want to override Foo for testing. I can extend the Bindings class and override the field/getter that returns Foo. and in my test setup, I set bindings with this new instance. Now when Fizz is created, the MockFoo instance is used instead of Foo
class MockFoo implements Foo {}
class BindingsOverride extends Bindings {
#override
final Foo foo = new MockFoo();
}
void main() {
bindings = new BindingsOverride();
}
Edit: In an earlier version I was using a static class. I don't think you need to refer to foo and bar through the bindings instance, you can just refer to the members directly.
This is my solution for this problem. First I created a dart file named injector.dart with this code:
// the singleton is private to this package
final _injector = new _Injector();
// expose depedencies
final foo = _injector.foo;
final bar = _injector.bar;
class _Injector{
// create a singleton
_Injector._internal();
static final _singleton = new _Injector._internal();
factory _Injector() {
return _singleton;
}
// the dependecies
Foo get foo => new Foo();
Bar get bar => new Bar();
}
This is how the code work, first we create a singleton class _Injector that creates needed dependencies and then exposes these dependencies with top-level variables. This way the dependencies are accessible anywhere the injector.dart package is accessible.
What do you think guys? is this good or is there a better implementation? Thanks

What is the idiomatic Groovy and Grails way of casting to a Domain Model class?

Given the Grails Domain Classes "Apple.groovy" and "Orange.groovy", not strictly related, and the following Grails Service invoked from the Controllers:
package test
import grails.transaction.Transactional
import javax.servlet.http.HttpServletRequest
#Transactional
class UploadService {
def uploadApple(HttpServletRequest request, Apple o) {
def file = request.getFile('payload')
o.payload = file.getBytes()
o.filename = file.originalFilename
o.contentType = file.contentType
o.save(flush:true)
}
def uploadOrange(HttpServletRequest request, Orange o) {
def file = request.getFile('payload')
o.payload = file.getBytes()
o.filename = file.originalFilename
o.contentType = file.contentType
o.save(flush:true)
}
}
How would one go about unifying this code under a common method? I was hoping Groovy's optional types would handle this for me, but I can't seem to be able invoke .save() successfully if I remove the types from the method signature.
Thanks in advance
Avoid passing request to service and pass File to service. Did you try it this way?
def upload(file, obj) {
obj.payload = file.getBytes()
obj.filename = file.originalFilename
obj.contentType = file.contentType
obj.save(flush:true)
}
Unlike Java, Groovy does duck typing. Typing is concerned with assigning a type to any object. Duck typing is concerned with establishing the suitability of an object for some purpose.
Now you have to be careful because this will not work for every object. The reason that it works for Apple and Orange is because both have exactly the same set of attributes and attribute types.
One would wonder, why you would have two different domain that behave exactly the same, but that's obviously is a different discussion.
In Grails 3, domain classes implement the GormEntity trait, which is where the save() method comes from. But that doesn't solve the issue with the payload, filename, and contentType properties.
What you can do is create an interface which declares the methods and properties common to both domain classes and also implements org.grails.datastore.gorm.GormEntity. Then, have the domain classes implement the interface:
interface Uploadable extends GormEntity {
byte [] payload
String filename
String contentType
}
class Apple implements Uploadable {
byte [] payload
String filename
String contentType
}
Then, you can use the interface in your service.
#Transactional
class UploadService {
def upload(HttpServletRequest request, Uploadable o) {
def file = request.getFile('payload')
o.payload = file.getBytes()
o.filename = file.originalFilename
o.contentType = file.contentType
o.save(flush:true)
}
}
Note: Since Grails injects the GormEntity trait into the domain classes automatically, I don't know what happens if you use it explicitly as shown.

Grails: How to mock properties for domain object with non-domain abstract base class

I have a grails 2.2.4 app with a domain class Monster:
class Monster {
int aggression
}
I can mock and test it like so:
import spock.lang.*
class MonsterSpec extends Specification {
def "property mocks work"() {
given:
def m = Mock(Monster)
m.aggression >> 5
expect:
m.aggression == 10
}
}
Recently I decided to give it an abstract base class (not a domain object itself) so that I could share method implementations among my many Monster-like classes:
abstract class Entity {} // Not under /domain
class RefactoredMonster extends Entity {
int aggression
}
But then a thousand simple tests all broke, like so:
import spock.lang.*
class MonsterSpec extends Specification {
def "property mocks work"() {
given:
def m = Mock(RefactoredMonster)
m.aggression >> 10
expect:
m.getAggression() == 10 // This works
and:
m.aggression == 10 // This fails! m.aggression is null!
}
}
What on Earth is going on? The problem goes away if I make Entity concrete, but then of course I can't hydrate any Monster objects since Hibernate doesn't know what to do with Entity (and I don't want to make Entity a domain object, though I suppose I will if I really must).
What am I missing?
The problem is GORM expects the super class to be a domain class.
With Groovy 2.0, which is what Grails 2.2.4 has, you can use compile-time mixins to add methods to a class. This allows for method reuse without inheritance.
The Entity can remain as not a domain class, but it must be a concrete class. Then, instead of subclassing, use it as a mixin.
#Mixin(Entity)
class RefactoredMonster {
int aggression
}
An alternative
Since you need the ability to override methods, as you said, Mixins are out.
Looking at this from a higher level, a potential issue is the architecture/design. Inheritance is meant to represent is-a relationships (ex. a Dog is an Animal). But when inheritance is used primarily as a way to reuse methods, it can lead to... a mess.
It may be better to forgo inheritance and choose has-a (delegation) instead. This would allow you to reuse behaviour and override it when needed. Unfortunately, Groovy 2.0 doesn't support #Delegate. So the following example is going to have more boilerplate code than the same thing coded in Groovy 2.4 would:
interface Flier {
def fly();
}
class FlierImp {
def fly() { "I'm fying! WOOT!" }
}
class RealDuck implements Flier {
def flier
RealDuck() {
flier = new FlierImp() // Purposely not using injection
}
def fly() {
flier.fly()
}
}
class RubberDuck implements Flier {
def fly() { "I don't fly" }
}
def duck = new RealDuck()
def rubberDuck = new RubberDuck()
assert duck.fly() == "I'm fying! WOOT!"
assert rubberDuck.fly() == "I don't fly"
In the example above RealDuck and RubberDuck represent domain classes (which is why I'm not injecting the flier). The flying behaviour is demanded by an interface and implemented either via a class which only implements the behaviour (FlierImp), or by implementing it directly, as shown in RubberDuck.

Dagger: Override #Provides-Method in Scoped Module

Let us suppose the following situation. There is a global module AppModule, a scoped module ScopedModule, a class Main and a class Foo in an application's main variant. Moreover, there is a debug variant with a module DebugAppModule, a module DebugScopedModule and a class Bar. Only the debug variant may know about Bar.
The main variant contains the following relevant code excerpts.
#Module AppModule { /*..*/ }
#Module(injects=Main.class, addsTo=AppModule.class)
ScopedModule { #Provides Foo provideFoo() { return new Foo(); } }
class Main { scopedGraph = graph.plus(new ScopedModule(this)); }
class Foo { /*..*/ }
// In the entry point of the application
ObjectGraph.create(new AppModule());
The debug variant contains the following relevant code excerpts.
#Module(addsTo=AppModule.class, overrides=true) DebugAppModule { /*..*/ }
#Module(injects=Main.class, addsTo=DebugAppModule.class, overrides=true)
DebugScopedModule { #Provides Foo provideFoo() { return new Bar(); } }
class Bar extends Foo { /*..*/ }
// In the entry point of the application
ObjectGraph.create(new AppModule(), new DebugAppModule());
My research and experimentation revealed that it is not possible to override #Provides-methods in scoped modules, i.e. when plusing a module. See for example How to Mock Dagger Activity Object Graphs. That is, in the debug variant whenever a Foo is injected it still would be a Foo and not a Bar. This makes sense because the class Main has a fixed dependency to ScopedModule (note the new).
It seems to me that there should be a way to inject scoped modules themselves – meta-injection so to say :). That is, AppModule could provide ScopedModule for Main. The problem is that ScopedModule's constructor needs an instance of Main and so AppModule would need to retain an instance of Main and that would not fly (e.g. in an Android-specific context where Main would be an Activity).
So what is the best alternative way to achieve the effect of overriding #Provides-methods when using scoped modules?
With the latest version of Dagger, overriding #Provided methods are not permitted.
I found a good solution here. Thanks to #vaughandroid
Basically,
When you are providing your module into your component, you can override your methods.
MyComponent component = DaggerMyComponent.builder()
.appModule(new AppModule() {
#Override public Foo provideFoo() {
return new Bar();
}
})
.build();
This has worked for me and I guess it'll work for you.

Resources