Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Adam Warski
    @adamw
    @novakov-alexey no, as wire is a macro, it generates code, so in the compiled version it is (or at least should) be identical as if you wrote the code by hand. So a wire[T] invocation becomes new T(...) at compile-time
    Alexey Novakov
    @novakov-alexey
    yeah, this confirms the spec in README :-(
    ok, thanks @adamw
    Felix Palludan Hargreaves
    @hejfelix
    Importing a member from my config class causes this weird error:
    Found multiple values of type [io.clutchpower.pancakes.config.S3Config]: [List(copy$default$2, s3)]
    Adam Warski
    @adamw
    @hejfelix I guess you'd have to provide some more code to be able to say why this happens :)
    Johannes Ebbighausen
    @johannes-ebbighausen

    Hey all,
    I'm working on a Play-application. And I wired my userservice like this

    lazy val userService: UserService = wire[UserService]

    and the userservice is injected into any class

    class X(val userService: UserService)

    but how can I inject the userService into an object or a trait?

    object MyValidator { def isUnique(username: String): Boolean = userService.findBy(sqls.eq(userDao.s.username, username)).isDefined
    }
    Adam Warski
    @adamw
    you need to make MyValidator parametrised itself, if you want to sue the dependency
    so class MyValidator(userService: UserService)
    @johannes-ebbighausen ^
    Johannes Ebbighausen
    @johannes-ebbighausen

    thx @adamw So what about traits, I can only mixin the dependency in an implementing class right?

    trait X {
    val userService: UserService
    }
    
    class Y(_userService: UserService) extends X {
    override val userService = _userService;
    }

    whould be nice if there is a way to inject the dependency right in the trait.

    Adam Warski
    @adamw
    @johannes-ebbighausen you can do: class Y(val userService: UserService) extends X
    this overrides the value automatically
    Wojtek Pituła
    @Krever
    Hey @adamw , Have you considered macwire support for cats.effect? Basically handling Resources
    Adam Warski
    @adamw
    @Krever not yet, how would that look like? :)
    Johannes Ebbighausen
    @johannes-ebbighausen
    thanks alot
    Wojtek Pituła
    @Krever

    I could imagine something like wireResource[F, T]: Resource[F, T] that will automatically pick up all the dependencies, supporting case when dependency is available as Resource[F, Dep] in which case it would flatmap all such dependencies. So

    class A(b: B, c:C, d:D)
    val bRes: Resource[F, B] = ???
    val cRes: Resource[F, C] = ???
    val d: D == ???
    val a: Resource[F, A] = wireResource[A]
    // which expands to 
    val a: Resource[F, A] = bRes.flatMap(b => cResource.map(c => new A(b,c,d)

    the problematic case is managing the boundaries, as this trivial expansion would result in reqacquiring B twice if its requested twice, which is probably not sth user wants in most of the cases.

    Wojtek Pituła
    @Krever
    the same would probably apply to IOin fact, some stuff is created effectfully but require no deallocation
    Adam Warski
    @adamw
    yeah, I guess resources are scarce enough to make you want to use them by hand :)
    Wojtek Pituła
    @Krever
    Its kind of painful, because I want to call use only in my main, and now I have to handle them manually in DI. I also find another "issue": wire doesnt pick up lamda parameters, so I can write myResource.map(x => wire[MySomething)
    Kai
    @neko-kai
    @Krever Use distage for wiring Resoprces - https://izumi.7mind.io/latest/release/doc/distage/basics.html#resource-bindings-lifecycle
    Since version 0.10 it doesn't use scala-reflect, so no problems with graal native image, concurrency etc. It's not compile-time, but you can test wiring correctness without actually executing any effects - https://izumi.7mind.io/latest/release/doc/distage/debugging.html#testing-plans
    Wojtek Pituła
    @Krever
    Yeah @neko-kai , almost tried that! But then 1) docs were a little bit intimidating (a lot of content, not very copy-and-paste-without-reading-friendly) 2) I really got used into compile-time DI and play left me with PTSD on runtime DI
    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