My application handles a lot of third party integrations. I have an abstract base class for third party integrations which specifies a bunch of methods that an integration class should handle – then certain integrations can be extended with additional functionality that is not available on all integrations.
Basically it looks like this:
abstract class Integration { ... }
trait SingleSignOn { ... }
class NormalIntegration extends Integration {}
class SingleSignOnIntegration extends Integration with SingleSignOn {}
I would like to be able to sort out all integrations that have a specific trait, and this is what I thought of as the basic solution:
val allIntegrations: Seq[Integration] = ...
def integrationsWithTrait[T]: Seq[Integration] = {
allIntegrations.filter(_.isInstanceOf[T])
}
The usage is:
val singleSignOnIntegrations = integrationsWithTrait[SingleSignOn]
The issue is that isInstanceOf[T] always returns true (meaning I end up with singleSignOnIntegrations == allIntegrations), while hard coded isInstanceOf[SingleSignOn] works as intended.
How do I fix integrationsWithTrait to work as I intend?
This will work:
def integrationsWithTrait[T](implicit tag: scala.reflect.ClassTag[T]): Seq[Integration] = {
allIntegrations.filter(tag.runtimeClass.isInstance)
}
Scalac will inject ClassTag instance for every class that this method will be called with. This will allow to access the Class object in runtime and verify if the class is the instance of given class/trait.
I think the original code doesn't work because of type erasure.
Related
This is kind of a weird use-case and I need some help in figuring out how to use Assisted/Providers/FactoryModuleBuilders in conjunction with each other. Ignore the absence of #Singleton. This is just an example.
A set of traits belonging to a library I cannot change have the following pattern. It uses Cake Pattern.
trait A { //Has abstract methods and abstract service 'webService' }
trait B extends A { //First Concrete Service Implementation assigned to 'webService' }
trait C extends A { //Second Concrete service Implementation assigned to 'webService' }
Since the traits cannot be directly injected, I created a wrapper that would allow them to be injected
BB extends B
CC extends C
In my code, I have a Controller that depends on a Service, that in turn depends on the library. The service should be able to either use "BB" or "CC" depending on what the controller needs. So the components look like the following
I create my service as
//Note: Uses 'trait A' with #Assisted
class SomeWebServiceComponent #Inject()(#Assisted aInstance: A, foo: Foo){
//Do something with aInstance
}
The Factory to create this (should be created by Guice by using FactoryModuleBuilder)
class SomeServiceFactory {
def getWebServiceComponent(a:A) SomeWebServiceComponent
}
The FactoryModule will look something like this
class ApplicationModule extends AbstractModule {
override def configure() = {
install(new FactoryModuleBuilder().build(classOf[SomeServiceFactory]))
}
}
I don't mind annotating the controllers with the actual classes that I need.
class OneController #Inject()(factory: SomeServiceFactory, bb: BB) extends Controller {
val webServiceComponent = factory.getWebServiceComponent(bb)
}
class AnotherController #Inject()(factory: SomeServiceFactory, cc: CC) extends Controller {
val webServiceComponent = factory.getWebServiceComponent(cc)
}
With this setup, I get errors of the following kind
No implementation for 'A' annotated with #com.google.inject.assistedinject.Assisted(value=) was bound
I need to understand how I can tell Guice that there are two implementations for Trait A, namely, BB and CC and the choice will be supplied at runtime.
Is there a way to achieve this use-case?
Ok, I created a separate project to test this whole scenario.
And it works the way the question is framed.
It turns out, the test cases that I were using, were not currently using GuiceInjection directly. The error message was however, so specifically related to GuiceInjection that I never investigated if the test setup was correct.
Changing the test base, resolved the issue.
I would like to develop a framework in which users may inject their own code inside our platform, without knowing some of our implementation details that may change in near future (e.g Database type).
I have splitted the code into two distinct projects:
One containing public APIs
One containing the server-side implementation
However, I would like they can test their code, with a kind of default implementation of some of this API.
For instance, in the public API:
trait UserDatabase {
def getAllUserInfo : List[UserInfo]
...
}
trait ExecutesOnServer{
def doWhaterverYouWant(db <: UserDatabase ) : Unit
}
In the user code:
class ExecutesOnServerImpl{
#override def doWhaterverYouWant(db <: UserDatabase) : Unit {
db.getAllUserInfo.foreach(println)
}
}
Now in the private implementation:
class MySQLUserDatabase extends UserDatabase {
#override def getAllUserInfo : List[UserInfo] = mysql.query(...)
...
}
I would like the user to have access a kind of default impl like LocalTextFileUserDatabase to test their code, and this is replaced my the server side one on the server.
What is the best way to do this ?
Thanks for your help
You can inject different concrete implementations depending on the current environment. For example, if SERVER_ENV == "local" you'll create an instance of LocalTextFileUserDatabase otherwise MySQLUserDatabase.
I'm new to Scala (and functional programming as well) and I'm developing a plugin based application to learn and study.
I've cretead a trait to be the interface of a plugin. So when my app starts, it will load all the classes that implement this trait.
trait Plugin {
def init(config: Properties)
def execute(parameters: Map[String, Array[String]])
}
In my learning of Scala, I've read that if I want to program in functional way, I should avoid using var. Here's my problem:
The init method will be called after the class being loaded. And probably I will want to use the values from the config parameter in the execute method.
How to store this without using a var? Is there a better practice to do what I want here?
Thanks
There is more to programming in a functional way than just avoiding vars. One key concept is also to prefer immutable objects. In that respect your Plugin API is already breaking functional principles as both methods are only executed for their side-effects. With such an API using vars inside the implementation does not make a difference.
For an immutable plugin instance you could split plugin creation:
trait PluginFactory {
def createPlugin (config: Properties): Plugin
}
trait Plugin {
def execute ...
}
Example:
class MyPluginFactory extends MyPlugin {
def createPlugin (config: Properties): Plugin = {
val someValue = ... // extract from config
new MyPlugin(someValue)
}
}
class MyPlugin (someValue: String) extends Plugin {
def execute ... // using someConfig
}
You can use a val! It's basically the same thing, but the value of a val field cannot be modified later on. If you were using a class, you could write:
For example:
class Plugin(val config: Properties) {
def init {
// do init stuff...
}
def execute = // ...
}
Unfortunately, a trait cannot have class parameters. If you want to have a config field in your trait, you wont be able to set its value immediately, so it will have to be a var.
I tried to use cake pattern in my project and liked it very much, but there is one problem which bothers me.
Cake pattern is easy to use when all your components have the same lifetime. You just define multiple traits-components, extend them by traits-implementation and then combine these implementations within one object, and via self-types all dependencies are automatically resolved.
But suppose you have a component (with its own dependencies) which can be created as a consequence of user action. This component cannot be created at the application startup because there is no data for it yet, but it should have automatic dependency resolution when it is created. An example of such components relationship is main GUI window and its complex subitems (e.g. a tab in notebook pane) which are created on user request. Main window is created on application startup, and some subpane in it is created when user performs some action.
This is easily done in DI frameworks like Guice: if I want multiple instances of some class I just inject a Provider<MyClass>; then I call get() method on that provider, and all dependencies of MyClass are automatically resolved. If MyClass requires some dynamically calculated data, I can use assisted inject extension, but the resulting code still boils down to a provider/factory. Related concept, scopes, also helps.
But I cannot think of a good way to do this using cake pattern. Currently I'm using something like this:
trait ModelContainerComponent { // Globally scoped dependency
def model: Model
}
trait SubpaneViewComponent { // A part of dynamically created cake
...
}
trait SubpaneControllerComponent { // Another part of dynamically created cake
...
}
trait DefaultSubpaneViewComponent { // Implementation
self: SubpaneControllerComponent with ModelContainerComponent =>
...
}
trait DefaultSubpaneControllerComponent { // Implementation
self: SubpaneViewComponent with ModelContainerComponent =>
...
}
trait SubpaneProvider { // A component which aids in dynamic subpane creation
def newSubpane(): Subpane
}
object SubpaneProvider {
type Subpane = SubpaneControllerComponent with SubpaneViewComponent
}
trait DefaultSubpaneProvider { // Provider component implementation
self: ModelContainerComponent =>
def newSubpane() = new DefaultSubpaneControllerComponent with DefaultSubpaneViewController with ModelContainerComponent {
val model = self.model // Pass global dependency to the dynamic cake
}.asInstanceOf[Subpane]
}
Then I mix DefaultSubpaneProvider in my top-level cake and inject SubpaneProvider in all components which need to create subpanes.
The problem in this approach is that I have to manually pass dependencies (model in ModelContainerComponent) down from the top-level cake to the dynamically created cake. This is only a trivial example, but there can be more dependencies, and also there can be more types of dynamically created cakes. They all require manual passing of dependencies; moreover, simple change in some component interface can lead to massive amount of fixes in multiple providers.
Is there a simpler/cleaner way to do this? How is this problem resolved within cake pattern?
Have you considered the following alternatives:
Use inner classes in Scala, as they automatically have access to their parent class member variables.
Restructuring your application in an actor based one, because you will immediately benefit of:
Hierarchy / supervision
Listening for creation / death of components
Proper synchronization when it comes to access mutable state
It will probably be helpful having some more code to provide a better solution, can you share a compiling subset of your code?
Let's say we have a program that has only two components: one contains the business logic of our program and the other one contains the dependency of this program, namely printing functionality.
we have:
trait FooBarInterface {
def printFoo: Unit
def printBar: Unit
}
trait PrinterInterface {
//def color: RGB
def print(s: String): Unit
}
For injecting the fooBar logic, the cake-pattern defines:
trait FooBarComponent {
//The components being used in this component:
self: PrinterComponent =>
//Ways for other components accessing this dependency.
def fooBarComp: FooBarInterface
//The implementation of FooBarInterface
class FooBarImpl extends FooBarInterface {
def printFoo = printComp.print("fOo")
def printBar = printComp.print("BaR")
}
}
Note that this implementation does not leave any field unimplemented and when it comes to mixing all these components together, we would have:
val fooBarComp = new FooBarImpl. For the cases where we only have one implementation, we don't have to leave fooBarComp unimplemented. we can have instead:
trait FooBarComponent {
//The components being used in this component:
self: PrinterComponent =>
//Ways for other components accessing this dependency.
def fooBarComp: new FooBarInterface {
def printFoo = printComp.print("fOo")
def printBar = printComp.print("BaR")
}
}
Not all components are like this. For example Printer, the dependency used for printing foo or bar needs to be configured and you want to be able to print text in different colours. So the dependency might be needed to change dynamically, or set at some point in the program.
trait PrintComponent {
def printComp: PrinterInterface
class PrinterImpl(val color: RGB) extends PrinterInterface {
def print(s:String) = ...
}
}
For a static configuration, when mixing this component, we could for example have, say:
val printComp = PrinterImpl(Blue)
Now, the fields for accessing the dependencies do not have to be simple values. They can be functions that take some of the constructor parameters of the dependency implementation to return an instance of it. For instance, we could have Baz with the interface:
trait BazInterface {
def appendString: String
def printBar(s: String): Unit
}
and a component of the form:
trait BazComponent {
//The components being used in this component:
self: PrinterComponent =>
//Ways for other components accessing this dependency.
def bazComp(appendString: String) : Baz = new BazImpl(appendString)
//The implementation of BazInterface
class BazImpl(val appendString: String) extends BazInterface {
def printBaz = printComp.print("baZ" + appendString)
}
}
Now, if we had the FooBarBaz component, we could define:
trait FooBarBazComponent {
//The components being used in this component:
self: BazComponent with FooBarComponent =>
val baz = bazComp("***")
val fooBar = fooBarComp
//The implementation of BazInterface
class BazImpl(val appendString: String) extends BazInterface {
def PrintFooBarBaz = {
baz.printBaz()
fooBar.printFooBar()
}
}
}
So we have seen how a component can be configured:
statically. (mostly the very low level dependencies)
from inside another component. (usually it's one business layer configuring another business layer, see "DEPENDENCIES THAT NEED USER DATA
" in here)
What differed in these two cases is simply the place where the configuration is taking place. One is for the low level dependencies at the very top level of the program, the other is for an intermediate component being configured inside another component. Question is, where should the configuration for a service like Print take place? The two options we have explored so far are out of the question. The way I see it, the only options we have is adding a Components-Configurer that mixes in all the components to be configured and returns the dependency components by mutating the implementations. Here is a simple version:
trait UICustomiserComponent {
this: PrintComponent =>
private var printCompCache: PrintInterface = ???
def printComp: PrintInterface = printCompCache
}
obviously we can have multiple such configurer components and do not have to have only one.
I have a Social object, responsable of connecting to Twitter, facebook, etc, and retrieve provider info for the specified user
For each provider I implemented a singleton TwitterAdapter, all inheriting from an abstract class SocialAdapter
here's the code: https://github.com/RestOpenGov/ideas-ba/blob/master/webservice/app/services/security/SocialConnector.scala#L98
For testing, I would obviously like to mock the TwitterAdapter, so that instead of connecting with twitter it returns some fixed response.
One solution I've found was to inject the list of adapters using an implicit parameter. The problem with this solution is that the Social.retrieveSocialProviderInfo is called from other functions, so I have to pass around the implicit List[SocialAdapter] parameter though all the call chain, like this:
def createApplicationToken(accessToken: AccessToken)
(implicit adapters: List[SocialAdapter] = Social.defaultAdapters)
: Either[List[Error], ApplicationToken] = {
// go to social info provider and fetch information
retrieveProviderInfo(accessToken).fold(
[...]
def retrieveProviderInfo(accessToken: AccessToken)
(implicit adapters: List[SocialAdapter] = Social.defaultAdapters)
: Either[List[Error], IdentityProviderInfo] = {
[...]
and finally
object Social {
val defaultAdapters = List(TwitterAdapter, FacebookAdapter)
def retrieveSocialProviderInfo
(accessToken: AccessToken)
(implicit adapters: List[SocialAdapter] = Social.defaultAdapters) // adapters can be injected
: Option[IdentityProviderInfo] = {
[...]
You get the idea
It works fine, normally I just ignore the second group of parameters and pick the default from Social.defaultAdapters, I only set it to List(MockTwitterAdapter, MockFacebookAdapter) when testing, but I'm cluttering the code just to be able to test it.
The other solution would be to make Social.defaultAdapters a var (instead of a val) and just change it for testing, normally in production mode it would always have the same value.
I think this must be a pretty common scenario. Is there a better strategy to handle these situations? Or maybe some way to extend the scope of the implicit assignment? Or shall I just go with a full-featured dependency injection framework?
A simple approach can be to just use traits all along:
// you can test this trait and override the adapters as you wish
// by overriding the defaultAdapters member
trait Social {
implicit val defaultAdapters = List(TwitterAdapter, FacebookAdapter)
def retrieveSocialProviderInfo(accessToken: AccessToken):
Option[IdentityProviderInfo] = ...
}
// you can use this object directly in your production code
// if you don't want to mix it in
object Social extends Social
// or use the trait by mixing it with another
trait Application extends Social {
def createApplicationToken(accessToken: AccessToken):
Either[List[Error], ApplicationToken] = {
// the defaultAdapters are accessible to the
// retrieveProviderInfo method
retrieveProviderInfo(accessToken).fold(...)
}