Replies: 3 comments 8 replies
-
Hi, I already tought a lot about this and my main concern about this is I don't want Akkurate to manage any kind of singletons in its own codebase. My first response was that users should wrap Akkurate by themselves and provide a default configuration. For example: fun <T> AcmeValidator(block: Validatable<T>.() -> Unit) = Validator(Configuration {
defaultViolationMessage = "The field contains an invalid value"
}, block)
fun main() {
AcmeValidator<String> {
isNotEmpty()
}
} However, after reading your message and diving a bit more into this, I realize how complex this is. The To support those, the users would have to create a wrapper for each of the Validator functions. This is complex, error-prone and discouraging. So I agree, yes, global configuration should be something provided by Akkurate! However, I still want to avoid Akkurate to manage any kind of singleton to store the global configuration. So here's my take: // Declare as many preconfigured validators you need, instead of a single global configuration.
val BooksValidator = Validator.preconfigured(Configuration {
rootPath("books")
})
val OrdersValidator = Validator.preconfigured(Configuration {
rootPath("orders")
})
// For each preconfigured validator, you can override its configuration, provide
// contextual values, and even use suspendable code.
fun main() {
// Simple validator
BooksValidator<String> {
isNotEmpty()
}
// Configuration overridden
BooksValidator<String>(Configuration { defaultViolationMessage = "This is wrong" }) {
isNotEmpty()
}
// With contextual values
BooksValidator<SomeDao, String> { dao ->
isNotEmpty()
constrain { /* use the dao */ }
}
// Suspendable validator
BooksValidator.suspendable<String> {
isNotEmpty()
// call some suspendable code
}
}
Akkurate doesn't store any kind of configuration, its up to the user. As a bonus, it is also possible to create multiple configurations for various use cases. Is this something that would fit your situation? |
Beta Was this translation helpful? Give feedback.
-
My concern is right now there is no way to enforce usage of these predefined declarations, everybody can still declare validators using default factory methods without our default configuration. Such enforcement might be implemented with some custom lint rules, which I know how to do only for android linter, never wrote rules for other. Another possibility is to move entrypoints into a separate module, this way it can be applied using api configuration to "proxy" project module where actual entrypoint would be defined. Actually, I like this option quite a lot after thinking about it for some time. What do you think? Maybe you have other ways in mind how can this be done? Also, can you please elaborate a little bit more on you position regarding singletons? |
Beta Was this translation helpful? Give feedback.
-
Let me try to sum up what we got.
Please correct me if I misundertood you somewhere. |
Beta Was this translation helpful? Give feedback.
-
Hi! I notice that right now the only way to change validation config is to explicitly pass configuration object during
Validator
creation. This could be cumbersome if you want to change your configuration globally. One example might be to collect violations in debug version of your app but fail on first one in release version for better performance. Right now to do something like this you have to either pass config into every validator or to declare some wrapper method to create validators inside your code. I don't like both solutions so I'm curious if you see as an reasonable solution to instead add to the library some way to specify default globall configuration? If you ok with the idea, I'm ready to implement it.Oh, by the way another bonus of keeping default configuration instance somewhere would be reduced number of object creation. If I'm not mistaken right now every
Validator
creation also creates 2 instances ofConfiguration
(one for default value inValidator.invoke(...)
, another for default value inConfiguration.invoke(...)
). Instead we can just point to our default same instance. This might sound silly for some people, but I worked on some mobile projects where I had to do some evil black magic to decrease number of creating objects to reduce garbage collector load.Beta Was this translation helpful? Give feedback.
All reactions