I'm learning the Play! framework (2.3.x). I am confused about the meaning of the '#' character in front of the controller in route definitions like this:
POST /myresource/:id/custom #controllers.MyResource.custom(id: Long)
As much as I can infer from the context I've seen this in, it probably has to do with the exact controller implementation (object vs class). Or am I completely wrong in this? I can't find anything in the docs and the code I've seen isn't exactly explanatory. Can anyone explain?
According to the documentation:
Play supports generating two types of routers, one is a dependency
injected router, the other is a static router. The default is the
static router, but if you created a new Play application using the
Play seed Activator templates, your project will include the following
configuration in build.sbt telling it to use the injected router:
routesGenerator := InjectedRoutesGenerator
The code samples in Play’s documentation assumes that you are using
the injected routes generator. If you are not using this, you can
trivially adapt the code samples for the static routes generator,
either by prefixing the controller invocation part of the route with
an # symbol, or by declaring each of your controllers as an object
rather than a class.
The equivalent in Java would be static vs non-static.
Related
https://github.com/wsargent/play-jdk13-alpine-slim/blob/master/src/main/scala/com/example/myservice/AppComponents.scala
https://github.com/playframework/play-samples/blob/2.8.x/play-scala-starter-example/conf/routes
https://github.com/playframework/play-samples/blob/2.8.x/play-scala-rest-api-example/conf/routes
I see in Play there are 3 ways to specify routes, as shown above, which way is considered the recommended one? Which folder structure is better?
Your first code example uses a SIRD router, whereas the second example uses a generated router from a routes file.
The third example just uses a routes file which generates a router that passes control to another router for a specific prefix -- no matter whether this was generated or hand-coded. So, this is no different than the second example.
There is no clear advantage of one over the other. Using a routes files is usually more succinct and "easier", but you have more control when using the DSL to bind your routes to some actions.
The folder structure is also merely a matter of taste; go with the default layout and you should be fine.
"The ambiguity, is in the box" - Monty Python.
Autofac is having a problem resolving an interface. See attached solution.
The Interface, IAmbiguous, is defined in project ACommon. It is implemented in project AInjectable. The AInjectable project does not / cannot reference ACommon. The AInjectable project defines IAmbiguous as an existing item brought in with a file link.
The UI project calls ACommon Inject and attempts to register the AInjectable assembly. IAmbiguous is not ambiguous initially but after a builder.RegisterAssemblyTypes command it becomes "ambiguous in the namespace." There is no error thrown when the container is built but the registration is not there.
Registration can be done "AsImplementedInterfaces" if Named and Keyed is not used. But then there is no way to Resolve the registration because the service IAmbiguous is "ambiguous in the namespace."
This question was double-posted as an issue on Autofac. It is not an Autofac problem. I will copy/paste the answer from the issue in here; for future readers, if you want to see the repro solution, go check out the full issue
What you're doing by including the same interface in two different assemblies isn't something you should be doing. Note that by doing that, your AInjectable class is not implementing the interface from the ACommon project. It's implementing a different but identically named interface.
This sort of thing is a problem - having the same type (interface, class, whatever) name in two different assemblies. We even had a problem (#782) where we had a System.SerializableAttribute in Autofac as a shim for .NET Core. You really just can't do that.
You'll also see the same thing if you try to make a static extension method class that has the same namespace and name as some other static extension method class. Ambiguous references.
Without doing Reflection.Emit style code generation, you won't be able to declare an interface in one assembly ("Assembly A") and implement that interface in a different assembly ("Assembly B") without having Assembly B reference Assembly A. That's just how .NET works. What you're seeing is a manifestation of that when you use Autofac, but it's not caused by Autofac. It's caused by you doing something you shouldn't be doing in .NET.
The fix is to define your interfaces in a separate assembly that everyone implementing the interfaces can reference. (Or you can try to dynamically generate code using Reflection.Emit or Roslyn or something, but that's waaaay harder.)
In the silhouette implementation example found here, how in the template is the implicit 'env' value (of type Environment[User, CachedCookieAuthenticator]) used in line 28 of /app/controllers/SignUpController.scala, for example, defined using Guice?
I guess I do not understand how provideEnvironment in app/utils/di/SilhouetteModule.scala is used to "inject" the Silhouette Enviroment into SignUpController (for example) via the "injector" created in line 24 of app/Global.scala. I don't see provideEnvironment being used anywhere in the play-silhouette-slick-seed example, so I can't seem to figure out what values are given to its arguments (such as userService, authenticatorService etc).
This example of silhouette module use Guice for scala Dependency Injection framework. All bindings are configured in util.di.SilhouetteModule.scala file. There is another example where Dependency Injection is replaced by Cake pattern. look at this
[edited]In short:
If you look at the Global.scala file, you'll find the guice configuration. Guice is forced to create every controller. Every view is dependend on controllers and will be managed by guice too.
The SilhouetteModule.scala file, as was mentioned above, is for configuration Silhouette module. There are few methods annotated with #Provides. If you look at the Guice documentation. Such method is called by Guice every time it needs class type the method returns, for instance: each time guice need to inject Environment[User, CachedCookieAuthenticator] it call def provideEnvironment method because this method return such type.
Typesafe Config documentation and library examples make a point that type safety can be achieved by making a configuration object or nested objects with getter methods mapped to Config.getType(key) methods.
If I wrap config calls in something like this:
class MyConfig (cfg:Config) {
val language = cfg.getString("app.language")
val database = new {
val url = cfg.getString("db.url")
val port = cfg.getInt("db.port")
...
}
}
I can do decent looking calls like config.database.url. Neat. (That dot looks so much greater than underscore)
What I don't quite get is how to allow modifying properties and saving them - quoting documentation, config is immutable. My attempts so far turned into either a gross spaghetti (closures with var config) or horrendous boilerplate (modifying a plain object and creating a new config from it to save), so I turned here for help.
I'd appreciate if someone showed me a good pattern for programmatically modifiable configuration using Typesafe Config.
It is possible that Typesafe Config just isn't a right tool for the job. I have little use for it's powerful merging and inheritance capabilities, instead I mostly need a simple, concise, unicode-friendly and type-safe way to load and store properties. I already do have one, a reflection-based java lib working with annotated POJOs. Doesn't seem to be a lot of variety with configuration libraries in Scala. I may have been too eager to throw away my trusty java tools.
After migrating to Play-2.1 I stuck into problem that routes compiler stopped working for my routes file. It's been completely fine with Play-2.0.4, but now I'm getting the build error and can't find any workaround for it.
In my project I'm using cake pattern, so controller actions are visible not through <package>.<controller class>.<action>, but through <package>.<component registry>.<controller instance>.<action>. New Play routes compiler is using all action path components except for the last two to form package name that will be used in managed sources (as far as I can get code in https://github.com/playframework/Play20/blob/2.1.0/framework/src/routes-compiler/src/main/scala/play/router/RoutesCompiler.scala). In my case it leads to situation when <package>.<component registry> is chosen as package name, which results in error during build:
[error] server/target/scala-2.10/src_managed/main/com/grumpycats/mmmtg/componentsRegistry/routes.java:5: componentsRegistry is already defined as object componentsRegistry
[error] package com.grumpycats.mmmtg.componentsRegistry;
I made the sample project to demonstrate this problem: https://github.com/rmihael/play-2.1-routes-problem
Is it possible to workaround this problem somehow without dropping cake pattern for controllers? It's the pity that I can't proceed with Play 2.1 due to this problem.
Because of reputation I can not create a comment.
The convention is that classes and objects start with upper case. This convention is applied to pattern matching as well. Looking at a string there seems to be no difference between a package object and normal object (appart from the case). I am not sure how Play 2.1 handles things, that's why this is not an answer but a comment.
You could try the new # syntax in the router. That allows you to create an instance from the Global class. You would still specify <package>.<controller class>.<action>, but in the Global you get it from somewhere else (for example a component registry).
You can find a bit of extra information here under the 'Managed Controller classes instantiation': http://www.playframework.com/documentation/2.1.0/Highlights
This demo project shows it's usage: https://github.com/guillaumebort/play20-spring-demo