Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Objects with interface types fields doesn't get the concrete implementations of fields populated #6

Open
lucassaldanha opened this issue Jul 3, 2015 · 6 comments

Comments

@lucassaldanha
Copy link
Owner

This issue only affects the random object generation (with random data). For the fixture based generation it all goes well.

For now Playdoh will create objects with interface types but wont populate those concrete types. E.g. if the object has a Set type field, Playdoh will create an empty set when generating the object.

We need to make Playdoh populate those fields with data.

@lucassaldanha lucassaldanha added this to the 1.0 milestone Jul 3, 2015
@lucassaldanha
Copy link
Owner Author

The main example of this issue is when creating objects with fields of type Collection, Set or Map. We instantiate those fields with a default concrete implementation but those instance doesn't have any data.

@lucassaldanha lucassaldanha removed this from the 1.0 milestone Jul 7, 2015
@muditporwal
Copy link
Contributor

muditporwal commented Feb 20, 2018

To get this to work (generate random values) we would still need to get the Generic Type of the Collection.
As of now we are passing Class but this is causing type erasure of the super type.
So if we were to initiate random values for Collection we would not have the generic type Integer while invoking doBuild and we would be only left with doBuild(Class<Collection/HashSet>)

Would you have any suggestions for this implementation ?

@lucassaldanha
Copy link
Owner Author

Would you have any suggestions for this implementation?

One way that I thought was having a map of interfaces and the prefered concrete implementation class that would be used.

Another option would be scanning the classpath to find eligible concrete implementations of an interface and picking the first one based on some criteria (alphabetically, for example).

Also, it is important to give the user the opportunity to add their own interfaces and override the default mapping when desired.

As of now we are passing Class but this is causing type erasure of the supertype.

This is a good point. How can we go around the type erasure?

One last option could be creating an annotation that would take the concrete class and the generic type. This is not my favourite because it is quite intrusive in the code, but maybe we can have something as a last resort.

@muditporwal
Copy link
Contributor

muditporwal commented Mar 1, 2018

Also, it is important to give the user the opportunity to add their own interfaces and override the default mapping when desired

I would think the user can create a custom implementation map before building objects.
A configuration factory could help in case the user wants to define multiple configurations.
The object builders could use the configuration factory to find out the default implementation of the interface

This is a good point. How can we go around the type erasure?

Still wondering :)
Found this link while trying to figure out http://gafter.blogspot.com/2006/12/super-type-tokens.html

@lucassaldanha
Copy link
Owner Author

lucassaldanha commented Mar 8, 2018

Found this link while trying to figure out http://gafter.blogspot.com/2006/12/super-type-tokens.html

Really interesting article. I'll read it completely during the weekend and check if I find a way on how to apply this pattern in the project.

Let me know if you come up with something as well!

@lucassaldanha
Copy link
Owner Author

I think I found a way to do it. I'll try it on the weekend (feel free to try as well, as I might not find time this weekend).

  1. On the method createInstance(Class type) on the ObjectBuilderImpl, while we are scanning the class, we could get the declared fields (type.getDeclaredFields()). This will return an array of Field type.

  2. With the Field on hands, we can get the generic type with field.getGenericType(). This contains the information about the container class (i.e. List) and the generic type (i.e. String).

I'll play a little bit with it to see what I can do.

@lucassaldanha lucassaldanha added this to the 2.0 milestone Mar 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants