I have an abstract class that many classes extend. Everything is in src/groovy.
In my abstract class I would like to have a service injected that the child classes would inherit so I don't have to inject them in every single one.
abstract class Animal {
def noiseService
abstract Sound getSound()
}
class Dog extends Animal {
Sound getSound() {
noiseService.bark()
}
}
In my resources.groovy:
animal(com.thepound.Animal) { bean ->
noiseService = ref("noiseService")
}
This produced an error saying it couldn't instantiate the class because it is abstract, so I added this to the definition:
bean.abstract = true
Now I no longer get an error, however the services are always null in my child classes. How can I get this to work?
Here is what I ended up doing.
I followed Burt Beckwith's post here http://burtbeckwith.com/blog/?p=1017 to create an ApplicationContextHolder class.
Then
abstract class Animal {
def noiseService = ApplicationContextHolder.getBean("noiseService")
abstract Sound getSound()
}
Now this works
class Dog extends Animal {
Sound getSound() {
noiseService.bark()
}
}
I didn't have to put anything in resources.groovy for the Dog or Animal classes
If you want to instantiate Dog, just do this:
noiseService(com.whatever.DogNoiseService) { bean ->
}
animal(com.thepound.Dog) { bean ->
noiseService = ref("noiseService")
}
Related
I´m working on a legacy spring boot project that makes a strong reuse of a DTO class in a generic controller and in multiple services:
#PostMapping
controller.input(#RequestBody MyTypeDto type) { ... }
service.resolve(MyTypeDto type) { ... }
processor.send(MyTypeDto type) { ... }
I want to start decoupling it by creating another endpoint and making MyTypeDto an abstract class.
My biggest concern under all is the compatility with jackson.
public abstract class MyTypeDto { ... }
public class AnotherTypeDto extends MyTypeDto { ... }
public class AndAnotherTypeDto extends MyTypeDto { ... }
Is it considered a good practice?
As it is implied on your question, you controller endpoint is generic, it takes the input, creates the type, pass it to service based on subtype. Otherwise, you will end up many endpoints which all doing is creating the subtype and pass it to service.
If Jackson is your concern, Jackson has mechanism for subtypes. Please note you have to send one additional field which act as the discriminator (in this example, it is called type to decide which sub type to create.
#JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
#JsonSubTypes({#JsonSubTypes.Type(value = FirstSubDto.class, name = "First"),
#JsonSubTypes.Type(value = SecondSubDto.class, name = "Second")})
public abstract class MyTypeDto {
..
}
I've been working on an item system for my game in Unity. I am still pretty new to coding, but I am giving it my best effort.
My Item system Works by accessing interfaces with the data I need. While trying to assign my sprite from the interface to a private variable, I get the error "'Sprite' does not contain a constructor that takes 0 arguments." I have looked all over for solutions, and haven't found any fixes that have worked for me so far.
The Class I created to access the interface looks like this:
public class ISType : IISType {
[SerializeField] string _name;
[SerializeField] Sprite _icon;
ISType()
{
_name = "Type";
_icon = new Sprite(); }
public string Name
{
get
{ return _name; }
set
{ _name = value }
}
public Sprite Icon {
get
{ return _icon; }
set
{ _icon = value; }
}
}
If anyone can tell what is going on I would really appreciate the help! :)
It looks like Sprite does not contain a public constructor accepting zero arguments.
A class with no constructors defined will have a parameterless constructor.
public class MyClass { }
MyClass x= new MyClass(); // this is valid
However if it has any other constructors defined, this parameterless 'default' constructor is no longer 'a given'.
Difference between default constructor and paramterless constructor?
Answer by Nicole Calinoiu
The "default" constructor is added by the C# compiler if your class does not contain an explicit instance constructor. It is a public, parameterless constructor.
https://stackoverflow.com/a/10498709/5569485
public class MyClass {
public MyClass(string foo)
{
}
}
MyClass x= new MyClass(); // this is invalid
The class would have to manually define a parameterless constructor.
public class MyClass {
// parameterless constructor
public MyClass()
{
}
public MyClass(string foo)
{
}
}
MyClass x= new MyClass(); // this is valid again!
Sometimes no constructors are provided publicly, and a class instead provides static methods to instantiate the object.
public class MyClass
{
private MyClass()
{
}
public static MyClass Create()
{
return new MyClass();
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/private-constructors
A private constructor is a special instance constructor. It is generally used in classes that contain static members only. If a class has one or more private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class.
Without knowing more about the Sprite class, my guess is that there is a static method for creating instances of the Sprite
something like
Sprite sprite = Sprite.Create(...);
The answer is in the error. There is no constructor that takes 0 parameters for Sprite. Without seeing the code I'm guessing you made a custom constructor with parameters and didn't add a paramaterless one.
A default parameterless constructor would look like:
Sprite()
{}
Be sure to do a lot more reading and tutorials. This is fairly basic class information.
In Spring framework and Java world, there is an interesting object collector pattern that I use.
For example consider below -
public interface Calculator {
SomeOutput calculate(SomeInput input);
}
#Component
public class CalImpl1 implements Calculator {
public SomeOutput calculate(SomeInput input){
//some implementation
}
}
#Component
public class CalImpl2 implements Calculator {
public SomeOutput calculate(SomeInput input){
//some implementation
}
}
Now this can easily injected in another class using Spring DI
#Component
public class Main {
//This line collects all to implementors of this and set it here.
#Autowired
public List<Calculator> calculators;
//other methods
}
Now problem is I am not sure how same thing can be achieved in scala. I have done some search and found cake pattern (http://loicdescotte.github.io/posts/scala-di/) used in scala but that didn't seem to achieve same thing as object collectors like above. I also want to follow open close principle which I think gets violated in cake pattern but using object collectors I can easily achieve it.
is there a way achieve same object collectors like implementation in scala?
There are templates in lighbend activator that illustration using spring DI on Play, Akka and Scala applications. Please see this: https://www.lightbend.com/activator/templates#filter:spring
I haven't used Spring as DI, I usually use Guice (explicitly used because it's default on play framework 2) and Implicits parameters both as a compilation DI.
Sample:
class B
class X(x: Int)(implicit c: B)
//DI - mostly define in main method/application
implicit val c: B = new B
val x = new X(2)
Explicitly using java.util.List worked for me. This is not the prettiest solution but it shows that it basically works. Haven't tried that but implementing a corresponding PropertyEditor you could stick with the Scala types.
trait Calculator {
def calculate(input: SomeInput) : SomeOutput
}
#Component
class CalImpl1 extends Calculator {
override def calculate(input: SomeInput): SomeOutput = ...
}
#Component
class CalImpl2 extends Calculator {
override def calculate(input: SomeInput): SomeOutput = ...
}
#Component
class Main #Autowired()(calculators: java.util.List[Calculator]) {
// or inject field if constructor injection is not desired
// #Autowired
// var calculators: java.util.List[Calculator] = _
}
object Main {
def main(args: Array[String]) = {
val ctx = new AnnotationConfigApplicationContext("your package name here")
val main = ctx.getBean(classOf[Main])
// calculators should now be wired in the returned instance
}
}
I'm wanting to test a Grails controller that contains a bean (I'll move it to a Service when I get it working, but I just want to keep it simple now).
//resources.groovy
beans {
myBean(com.me.MyBean)
}
// MyBean.java
// this needs to be in java as it is playing with spring-data-neo4j
package com.me;
public class MyBean {
String show() {
return "Hello";
}
}
// TestController.groovy
package com.me
import com.me.MyBean
class TestController {
def myBean
def index() {
render myBean.show()
}
}
// TestControllerSpec.groovy
package com.me
import grails.test.mixin.TestFor
import spock.lang.Specification
import com.me.*
#TestFor(TestController)
class TestControllerSpec extends Specification {
def myBean
def setup() {
defineBeans {
myBean(com.me.MyBean) {bean->
bean.autowire = true
}
}
}
def cleanup() {
}
def "show() returns Hello"() {
when:
def rc = controller.myBean.show()
def rc2 = myBean.show()
then:
rc == "Hello"
rc2 == "Hello"
}
}
Within TestControllerSpec, myBean is null. controller.myBean is also null. I think this is because Spring is not picking the bean up and wiring it in. I gather that in unit tests not all spring beans are available, but what do I need to do to get controller.myBean to be instantiated and wired up correctly?
You must be mocking the myBean as below
def myBean = Mock(MyBean)
or
MyBean myBean = Mock()
and then stub out method for your need if required as below:
myBean.show >> "test data"
and then assign it to controller object which is already mocked for you.
controller.myBean = myBean
and there you go.
Or optionally you can stub out myBean and give stubbed implementations. For example,
MyBean myBean = Stub(){
show() >> {return "sample text"}
}
controller.myBean = myBean
The reason for doing this is we are not testing the integration of application entities like controller, views or domain but we are testing a single unit i.e. a method and hence we should be just testing it and for integration we should be using integration test cases which would be similar in everything except you won't require any mocking in normal scenarios.
Edit:
found another useful feature to mock services or beans using defineBeans closure as below:
defineBeans {
adapter(Adapter)
helperService(HelperService)
}
This will allow beans to be accessed from grailsApplication.
Hope it helps.
I am trying to autowire a list of beans of a given type into my Bootstrap.groovy.
Say, I have the below interface and classes.
interface Vehicle {
}
#Component
class Car implements Vehicle {
boolean byName = false
}
#Component
class Van implements Vehicle {
boolean byName = false
}
And my Bootstrap.groovy looks like this:
class Bootstrap {
List<Vehicle> vehicles
def init = { servletContext ->
println "Vehicles are ${vehicles}" // prints null
}
}
I am sure I have set up component scanning correctly as I can see normal beans being wired up. However, it looks like autowiring by type isn't happening, causing the Spring container to try to wire the list of Vehicles by name and failing in the process.
Any insights would be appreciated.
I am using Grails 2.4.3