Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Wojtek Pituła
    @Krever
    but maybe I will give it another shot, its my first service where I'm trying to go full FP in DI. Normally I just ignore safety in DI, as not many things can affect you when writing microservices (you deallocate only on exit and most of the stuff will be deallocated automatically then anyway)
    Kai
    @neko-kai
    @Krever There's a compile-time check macro, but tbh it's more for show since it only gets triggered on full rebuild - https://izumi.7mind.io/latest/release/doc/distage/distage-framework.html#compile-time-checks - it was still useful for me sometimes. I find just having a unit test jcheck if something's missing is very much good enough, though - I think it's impossible to test Guice without running the app, but with distage you can.
    I cleaned up the docs a lot, but I guess I should think more about the copypaste angle! They're all using mdoc now so copypaste should work well (scala-reflect caused issues with mdoc, so some examples were stale)
    Jinto Thomas
    @ttj4
    I am new to macwire. It might sound stupid, but I cannot figure a way to wire the following class Class BasicCredentials(key: String, secret: String)
    I tried to implement a factory method : def creds(secret: String, key: String) = wire[BasicAWSCredentials]
    but it's giving Error:Found multiple values of type [String]: [List(secret, key)] def creds(secret: String, key: String) = wire[BasicAWSCredentials]
    Przemek Sokół
    @falconepl
    That's because both key and secret are strings - so they have the same, general type while they mean different things. You should wrap key and secret in separate value classes or tag them with Tagged

    So you should have:

    case class Key(value: String) extends AnyVal
    case class Secret(value: String) extends AnyVal
    class BasicCredentials(key: Key, secret: Secret)

    or:

    trait Key
    trait Secret
    class BasicCredentials(key: String @@ Key, secret: String @@ Secret)
    Jinto Thomas
    @ttj4
    Thank you! @falconepl. Also could you please suggest if I should use the factory method to load say typesafe Config's? So there are some java static methods which return a class
    for example ConfigFactory.parseResource("somefile") returns a Config
    Przemek Sokół
    @falconepl
    Check out PureConfig library - https://pureconfig.github.io/
    It will allow you to get your configuration as an instance of some Config class, based on e.g. your application.conf content
    Jinto Thomas
    @ttj4
    Actually I am not exactly looking for config's alone. It was more like an example. Actually I am not clear how to do the wiring if I have a factory method (scala objects which returns a class instance or some java static method which returns a class instance
    This is from the example, is it restricted to companion objects alone?
    class A()
    
    class C(a: A, specialValue: Int)
    object C {
      def create(a: A) = new C(a, 42)
    }
    
    trait MyModule {
      lazy val a = wire[A]
      lazy val c = wireWith(C.create _)
    }
    Przemek Sokół
    @falconepl
    Sorry, I've misunderstood your question. I think that with wireWith you should be able to reference any object's method that returns some T instance, as long as Macwire is able to fill in all the arguments required by that method. So if we talking about some Java static method, it's almost certain that it would require some primitive types. If it does, I would suggest calling that method by hand and bring it to Macwire's scope instead:
    case class B(dependency: T)
    lazy val a: T = someJavaLibMethod(...)
    lazy val b = wire[B]
    Jinto Thomas
    @ttj4
    @falconepl Thank you! I was under the impression it's some sort of anti-pattern to call someJavaLibMethod directly
    Jinto Thomas
    @ttj4

    Hello everyone, I am trying to use wireWith with a factory method which accepts multiple parameters.

    class A
    class B
    class C
    
    object D {
      def bind(a: A, b: B) : C = new C
    }
    
    trait MyTrait {
      import com.softwaremill.macwire._
    
      lazy val a = wire[A]
      lazy val b = wire[B]
      lazy val c = wireWith(D.bind(a, _))
    }

    but I am getting missing parameter type for expanded function ((x$1) => D.bind(a, x$1)) lazy val c = wireWith(D.bind(a, _)).

    Kai
    @neko-kai
    @jinto-thomas Annotate it with B as in wireWith(D.bind(a, _: B))
    Artem Egorkine
    @arteme
    I have a play project that I'm converting from cake to macwire and everything went rather smooth, except... I wire the controllers and it goes all just fine, except for one it will complain recursive lazy value indexController needs type. I can rewrite the lazy val indexController = wire[IndexController] as manual instantiation, lazy val indexController = new IndexController(...), which works, but not the wire-variant. How do I go about debugging this?
    Wojtek Pituła
    @Krever
    @arteme Have you tried putting type ascription to the value as the error suggests?
    Artem Egorkine
    @arteme
    @Krever yes, it compiles, but I get an UinitializedFieldError at run-time
    Wojtek Pituła
    @Krever
    this sounds like recursive value indeed. Do you have field of type IndexController as a constructor parameter to IndexController?
    Artem Egorkine
    @arteme
    I found macwire.debug property, but i don't see anything immediately wrong with what macwire does. Starting to look with suspicion in the direction of the compiler itself ;)
    @Krever That's what I thought, but no, the only reference to IndexController is from the router
    Artem Egorkine
    @arteme
    @Krever okay, I figured it out. the "recursive value needs type error" is just telling me that I can't do val indexController = wire[IndexController]; do_stuff(indexController). Why, doesn't the compiler infer the type? and UinitializedFieldError was not related to wiring at all
    Artem Egorkine
    @arteme
    Is there a way to use macwire in a generic function? I basically need a factory that needs to wire the object and then call some methods on it... I was hoping I could do something like:
      def specialWire[T <: CtrlBase]: T = {
        val t: T = wire[T]
        // ... do something to t ...
        t
      }
    Adam Warski
    @adamw
    @arteme sorry, no, the T must be fully statically known at compile time
    Kai
    @neko-kai
    @arteme You can write a macro to summon functions generated by wire with implicits, or you can switch to distage which supports this directly:
      import distage.constructors.ClassConstructor
    
      def specialWire[T <: CtrlBase: ClassConstructor] = {
        ClassConstructor[T].map {
          t => 
          // ... do something to t ...
        }
      }
    Artem Egorkine
    @arteme
    @neko-kai : Thanks. Distage looks interesting, but too complicated for my use-case. I ended up just rewriting my code as do_something(wire[...]) for every CtrlBase sub-class instance I wire...
    Antoine Doeraene
    @sherpal
    Hello! I'm starting to use macwire with play framework (and actually zio). When I compile everything works out great, but when I use the dist command to package the app, there are dependencies which it doesn't find. Typically it fails with Cannot find a value of type: [zio.Runtime[services.models.usersdao.UsersDAO]] (which leads me to believe it's more of a problem with ZIO rather than play or the sbt-native-packager. Did you encounter something like this already? Thanks! (I'm using play 2.8 and scala 2.13)
    6 replies
    Joe Netti
    @nettijoe96
    Hi all. I am trying to integrate a repo tha uses play/macwire with bazel build system which has to has to point to a main class. Macwire generates the main class by applying the macro to my knowledge so I am not sure what to point to. Anyone run into this before?
    Adam Warski
    @adamw
    @nettijoe96 you have to write the main class yourself - inside, you might be using macwire to instantiate all of the dependencies, but that's all that macwire does. No generation of main classes :)
    Joe Netti
    @nettijoe96
    @adamw I see, I must be confused then. This example I'm looking at doesn't have a main: https://github.com/playframework/play-samples/tree/2.8.x/play-scala-macwire-di-example
    Rohan Sircar
    @rohan-sircar
    @nettijoe96 that's normal, play applications don't need to define a main class, they need to define a loader instead, and play calls it, as i understand. That's not something macwire is doing
    Btw, just wanted to say that I find macwire enough of a reason to choose scala over competing languages :)
    Joe Netti
    @nettijoe96
    ah i see, I thought it was macwire doing this. Thanks for the help!!
    pbj23000
    @pbj23000
    hi macwire'ers - i have what i hope is an easy question. i'm following the play tutorial at https://dvirf1.github.io/play-tutorial/posts/macwire and i have run into a sticky question. at this point in the tutorial we're wiring up previously "new"d services. This works fine if my constructors all take class-type arguments, but i'm also using the statsd client whose constructor's signature is val statsDClient: StatsDClient = new NonBlockingStatsDClient(prefix: String, host: String, port: Int) and i'm not at all sure how to bind those primitive arguments using macwire?
    pbj23000
    @pbj23000
    lol - i see i've asked a common question; i'll try using qualifiers and tagging!
    pbj23000
    @pbj23000
    alright - so i see how qualifiers and tagging work when i have control of the the constructor; what about when i don't (as in my case where i'm using "com.timgroup" % "java-statsd-client" % "3.1.0"'s NonBlockingStasDClient()) ?
    Antoine Doeraene
    @sherpal
    One option is to instantiate it manually. I don't know if such an answer is enough for you
    pbj23000
    @pbj23000
    right- or to wrap it seems to be my other option?
    kali786516
    @kali786516
    Hi Team I want to do something like this using macwire
    Trait SparkUtils {  
    def getSparkSession(val appName:String,val arg1:String) = {
          spark.session().conf("app",appName).conf("yarn.blah",arg1)
    }
    
    class SparkUtilsHelperClass(val appName:String,val arg1:String) extends SparkUtils {
        def getSparkSession() = {
         val someSparkSession = SparkUtils.getSparkSession(appName,arg1)
         return someSparkSession
        }
    }  
    
    Object MainObje {
       def main(args:Array[String]) = {
       val appName = args(0)
       val argg1 = args(1)
      //can I pass the above arguments to class with the help of macwire ?
       val wireClass = wire[SparkUtilsHelperClass]
       wireClass.getSparkSession
    }
    }
    kali786516
    @kali786516
    I want to pass the arguments to class without initiating class with arguments I would like macwire to figure out arguments which are initiated
    kali786516
    @kali786516
    is the above scenario possible
    kali786516
    @kali786516
    hi team
    Yakiv Yereskovskyi
    @yakivy

    Hi there. Is it possible to wire the whole object tree? Something like:

    class DatabaseAccess()
    class UserFinder(databaseAccess: DatabaseAccess)
    class UserStatusReader(userFinder: UserFinder)
    
    trait UserModule {
        import com.softwaremill.macwire._
    
        lazy val theUserStatusReader = wire[UserStatusReader]
    }

    that will generate:

    trait UserModule {
        lazy val meaninglessId1      = new DatabaseAccess()
        lazy val meaninglessId2      = new UserFinder(meaninglessId1)
        lazy val theUserStatusReader = new UserStatusReader(meaninglessId2)
    }
    Yakiv Yereskovskyi
    @yakivy
    @kali786516 I think https://github.com/softwaremill/macwire#qualifiers should help you. Here is an example:
    class Berry()
    trait Black
    trait Blue
    
    case class Basket(blueberry: Berry @@ Blue, blackberry: Berry @@ Black)
    
    lazy val blueberry = wire[Berry].taggedWith[Blue]
    lazy val blackberry = wire[Berry].taggedWith[Black]
    lazy val basket = wire[Basket]
    Yakiv Yereskovskyi
    @yakivy
    Hi again. About the question above… I was not able to find how to wire a whole object tree by any existed DI Scala lib, that is technically the only feature that I need from DI lib, so had to write own sketch:
    https://github.com/yakivy/jam/blob/master/core/src/jam/JamMacro.scala#L6
    I hope it will help someone. Cheers.