I am writing a custom plugin and to test it, I want to inject mock implementations. It is not just for testing but from API perspective too, I want to inject different implementations depending on the context. I am currently using Gradle 2.6 and I understand that it supports some form of Dependency Injection. I do not want to use Spring/Guice/HK2 since Gradle itself supports it. However, I am not able to find any information how to inject dependencies using Gradle 2.6 APIs.
For eg:
class CustomTask extends DefaultTask {
private SomeInterface interface
#Inject
CustomTask(SomeInterface interface) {}
#TaskAction
public void executeTask() {
interface.executeSomething()
}
}
So, essentially, I want to figure where to define bindings for different instances of SomeInterface and the mechanism to inject it into task or anywhere else like some custom classes.
Since this question was not closed, some information might still be useful for whoever runs into it.
I do not want to use Spring/Guice/HK2 since Gradle itself supports it.
You might have already seen the relevant discussion on the gradle forum.
https://discuss.gradle.org/t/dependency-injection-in-gradle-plugins/6538
We are currently working on this. Dependency injection is already available for internal Gradle services, but I'm guess you are wanting to inject your own collaborators. Our dependency injection will support this at some point.
As usually with Gradle, we can check whatever is in the oven.
https://github.com/gradle/gradle/tree/bd4fb1c396a695d55aeba9bc37e164a488c0b882/design-docs
This design document can give you a look into what one of the core maintainers thought is a good way to approach the problem. While it is not complete, I consider it quite valuable.
Unfortunately the document (along with the complete folder) has been removed on Sep 20, 2017 with the following message:
This has turned into a graveyard for ideas. It only serves to confuse
people at this point. We have found it more productive to either
use GitHub Epics and issues for smaller design questions
use Google Docs for larger topics (e.g. native publishing)
These documents quickly go out of date once a feature is implemented.
They are not a replacement for good user and code documentation.
Many of the documents are about features that we never ended up
implementing. Having those documents still around might lock us into a
certain way of thinking about a problem. Instead we should have a
fresh look at it when we actually want to start working on it.
Related
I want to write an RMI library in/for Ceylon (since I have not found one so far).
The first thing I need is a proxy. In Java I used something like
Proxy.newProxyInstance(classLoader, interfaces, handler);
1. Is there something equivalent in Ceylon? (haven't found something)
Attempting to write something like this my own, I came across this solution for the JVM using byte code manipulation.
Nifty and exactly what I want.
Notice, that this can even produce a proxy for a class, not only for interface like in Java. In Ceylon this is should be legit, since there are no fields and we can simulate the whole class with method calls.
2. If creating proxies for classes is a no-go just tell me.
Also, what is the Ceylon intuition/future about proxies? Shall there be (no) proxies?
In a future with proxies we have one major problem:
In Ceylon we have the default keyword, without it a method can not be refined/overwritten. This also results in final methods for the compiled Java output classes. Thereby (not even) the byte code manipulation can overwrite those and redirect them to an invocation handler/interceptor.
3. How do we deal with this?
I assume not at all? I totally get the idea of disallowing the refinement of methods and the default/final keywords, but this obstructs RMI/proxies for classes.
4. Are proxies for classes a bad idea?
And yes, there are so much more questions I am currently thinking about and investigating on: JS implementation, interfaces and default methods, etc
These points seem to be the most relevant at the moment, so let's start here.
You could try using this module I wrote:
https://github.com/gavinking/ceylon.proxy
Alternatively, if you're only targeting the JVM, you could just use Java's Proxy directly.
During further research I found:
1. Proxies are currently part of the Ceylon 1.4 milestone (issues regarding proxies).
3. Enabling EE mode for the ceylon compiler, removes the final keyword.
From this point on the solution I found works like intended and is exactly the same as the one provided by Gavin.
We are writing a new set of services and have decided to make them share a common interface... calling it a BaseService. The idea is that whenever anyone wants to develop a new service in our organization, they should be just able to extend and use this BaseService.
We have written a few other classes which also form a part of this base jar, it does things like handle transactions and connect to database using hibernate etc.
Right now all the services that extend the BaseService are a part of the same project (Eclipse + Maven), and some of the services are dependent on each other, but because they are in the same project we don't have a problem with dependencies.However, we expect 40-50 services to be written which would extend base service and would also be interdependent.
I am worried that the size of the base project would be huge and that just because when someone has to use one service they might have to depend on my base jar which has 50 services.
Is there a way that we can make some projects dynamically dependent on others?
Lets say I have a service A which depends on service B, when I build/compile Service A,it should be able to realize that it has a dependency on service B and automatically use the Service B jar.
I have heard of OSGi, will it solve my problem or is there a way I can do it with Maven or is there a simpler solution ?
Sorry about the long post !
Thanks in advance for your suggestions
It doesn't make any sense to "dynamically" manage project dependencies, since build dependencies are by definition not dynamic.
Your question, at least for the moment, seems to be entirely about how to build your code rather than about how to run it. If you are interested in creating a runtime system in which new service implementations can be dynamically added then OSGi may be the solution to look at. An extra advantage here would be that you could enforce the separation of API from implementation, and prevent the implementing services from invalidly depending on parts of your core module that you do not want them to have visibility of.
You could also use OSGi to manage evolution of your core service API through versioning; for example how do you communicate the fact that a non-breaking change has been made to the API versus a breaking change etc.
I would say there are two options depending if i understand your question correct. First one. You have already defined an interface (java term) and now you have different implementations of that. The simple solution for Maven would be to a have a module which is called for example: service-api and than this will be released and can be used by others as dependencies. On their side they simply implement the interface. No problem with the dependencies. If you are more talking about OSGi than you should take a look to maven-tycho.
As far as I understand, main purpose of dependency injection is to have all dependencies separated declaratively, so that we can easily review and change the dependency structure easily...right?
Then by using dependency annotations spread through out the code, aren't we just going back to non-centralized system (similar to simple new operator), which is harder to tweak?
#Autowired/#Inject annotations usually declare dependencies on interfaces rather than on concrete classes (as in the case of new), thus you still can control which implementations should be injected by controlling which beans are declared in the context. Also, these dependencies can be overriden manually.
#Component-family annotations can be controlled as well, since you can exclude particular classes from component scanning.
The purpose of dependency injection is to decouple the declaration of dependencies from the actual satisfying of those dependencies. How the declaration is done is an orthogonal issue.
#Autowired is a form of dependency declaration. Using #Autowired supports encapsulation. A class' injected dependencies are documented directly in the code instead of in another file.
These types of discussions have tendency to become religious so I'll stear clear of the "main purpose" definition and the semantics of whether this or that pattern is really and truly fulfilled.
I try to look at it like a tool that can offer certain features. For instance, using Spring (DI) is a good way to separate interfaces and implementations. Users of a particular interface need not know how to create the implementation (or where it resides). This is often something good. Using Spring also enables a whole lot of other stuff: AOP and AOP-driven features like transaction handling, scopeing and a whole bunch of pre-built integrations to other frameworks and technologies. Annotations make a lot of this easier and clearer and best of all, I don't have to use them where it's not practical or possible - there is always the option to configure it in XML instead.
What is the proper way to to use the OSGi LogService in a real world application? At first I figured I would use Declarative Services to create components if a class needs to log something. However, this means you have to declare a service component for just about every single class which seems like overkill and a pain to maintain. This is especially true when you need to make most of the classes into component factories that are just helper classes.
Also, this doesn't work very well for abstract classes and non-final classes as the developer extending the class has to make sure he/she declares a component with the same references as the base class. This is especially true in the system I'm developing that essentially provides a library containing abstract classes that other developers will use.
The current solution is providing static log methods that use a static instance of a LogService reference. However, the LogService provider treats all log messages as coming from the bundle that contains the static log class.
In OSGi (as in any environment) you want to stay away from static helpers as much as you can, so, the static log method solutions is not the best way to go here. As you run in an OSGi environment, you will want to use the LogService as a central, bundle- and service-aware conduit for all your logging. There are two cases to consider.
Legacy and library code
If the code you use needs logging functionality, but is not OSGi aware, you can build (or find) bridges to the LogService.
Code under your control
Assuming that all code under your control is supposed to be service-aware, it should use the LogService directly. For most components this is easy, but some cases need additional consideration.
For abstract classes, it all depends on what you use them for.
Are they base classes that help you with OSGi details? Then declarative services may not be your best bet, you could look into other dependency management mechanisms that handle inheritance differently.
Do they provide non-OSGi aware base functionality? This case should be no problem, as your concrete subclass will be registered as a component.
We all run into situation where library code seems to need logging; however, ask yourself whether it really does. Very generic code can rarely know what it should log. If it knows enough about your situation, it probably should be located in a component, delegating the details to the actual library code. For exceptional situations that warrant logging, you should probably use exceptions.
Do you really need to log from non-service-aware code? You can pass in a LogService to the helper methods (so at least we know on who's behalf this code is executing).
A special case to consider are long-running operations that are not OSGi-aware: if you give a service reference to, for instance, a worker thread which may run a very long time, you're asking for trouble, not only for logging.
I am a big fan of Dependency Injection and the Play Framework, but am having trouble seeing how the two could be exploited together.
There are modules for Spring and Guice, but the way that Play works makes it hard for me to see how DI could be beneficial beyond some quite simple cases.
A good example of this is that Play expects JPA work to be done by static methods associated with the entity in question:
#Entity
Person extends Model {
public static void delete(long id) {
em().find(id).remove();
}
//etc
}
So there is no need for a PersonManager to be injected into controllers in the way it might for a Spring J2EE application. Instead a controller just calls Person.delete(x).
Obviously, DI is beneficial when there are interfaces with external systems, as the concrete implementation can be mocked for testing etc., but I don't see much benefit for a self-contained Play application.
Does anyone have any good examples? Does anyone use it to inject a Manager-style class into Controllers so that a number of operations can be done within the same transaction, for example?
I believe from this sentence you wrote:
"Does anyone have any good examples? Does anyone use it to inject a Manager-style class into Controllers so that a number of operations can be done within the same transaction, for example?"
that before answering the DI question I should note something: transactions are managed automatically by Play. If you check the model documentation you will see that a transaction is automatically created at the beginning of a request, and committed at the end. You can roll it back via JPA or it will be rolled back if an exception is raised.
I mention this because from the wording of your sentence I'm not sure if you are aware of this.
Now, on DI itself, in my (not-so-extensive) experience with DI, I've seen it used mainly to:
Load the ORM (Hibernate) factory/manager
Load Service classes/DAOs into another class to work with them
Sure, there are more scenarios, but these probably cover most of the real usage. Now:
The first one is irrelevant to Play as you get access to your JPA object and transaction automatically
The second one is quite irrelevant too as you mainly work with static methods in controllers. You may have some helper classes that need to be instantiated, and some may even belong to a hierarchy (common interface) so DI would be beneficial. But you could just as well create your won factory class and get rid of the jars of DI.
There is another matter to consider here: I'm not so sure about Guice, but Spring is not only DI, it also provides a lot of extra functionalities which depend on the DI module. So maybe you don't want to use DI in Play, but you want to take advantage of the Spring tools and they will use DI, albeit indirectly (via xml configuration).
The problem in my humble opinion on the static initialization approach of Play! is that it makes testing harder. Once you approach the HTTP vs Object Orientation problem with static members and objects that carries the HTTP message data (request and response) you make a trade of having to create new instances for each request by the ability of make your objects loosely coupled with the rest of your project classes.
One good example of a different design are servlets, it also extends a base class but it approaches the problem with a single instance creation (by default, because there are configurations that enable more instances).
I believe that maybe a mix of the two approaches would be better, having a singleton of each controller would give the same characteristics of a full static class and would allow dependency injection of some kinds of object. But not the objects with request or session scope, once the controller would need to be created every new request. Moreover it would improve testability by inverting the control of dependency injection, thus allowing arbitrary injection points.
Dependencies would be injected by the container or by a test, probably using mocks for the heavy stuff that much likely would already have been tested before.
In my point of view, this static model pushes the developer away from testing controllers because extending FunctionalTest starts the application server, thus paying the price of heavy objects like repositories, services, crawlers, http clients, etc. I don't want to wait a lot of objects to be bootstrapped just to check if some code was executed on the controller, tests should be quick and clear to make developers love them as their programming assistant/guide.
DI is not the ultimate solution to use everywhere... Don't use DI just because you have it in your hands... In play, you don't need DI to develop controllers/models etc... but sometimes it could be a nice design: IMO, you could use it if you have a service with a well know interface but you would like to develop this service outside Play and test it outside play and even test your play project with just a dummy service in order NOT to depend on the full service implementation. Therefore DI can be interesting: you plug the service loosely in play. In fact, this is the original use case for DI afaik...
I just wrote a blog post about setting up a Play Framework application with Google Guice. http://geeks.aretotally.in/dependency-injection-with-play-framework-and-google-guice
I see some benefits, especially when a component of your application requires a different behavior based on a certain context or something like that. But I def believe people should be selective about what goes into a DI context.
It shows again that you should only use dependencies injection if you really have a benefit. If you have complex services it's useful, but in many cases it's not. Read the chapter about models in the play-documentation.
So to give you an example where you can use DI with play. Perhaps you must make a complex calculation, or you create a pdf with a report-engine. There I think DI can be useful, specially for testing. There I think the guice-module and spring-module are useful and can help you.
Niels
As of a year and some change later, Play 2.1 now has support for dependency injection in controllers. Here's their demo project using Spring 3, which lays it out pretty clearly.
Edit: here's another example using Guice and Scala, if that's your poison.