Comments (5)
I'm not sold to the concept of having two types provided by one class like this. Why not do it like this (if Foo
and Bar
are interfaces, what they should be)?
@Instance(type = FooBar::class)
internal class FooBar(): Foo, Bar {}
@Instance(type = Foo::class, classifier = "foo")
fun provideFoo(foobar: FooBar): Foo = foobar
@Instance(type = Bar::class, classifier = "bar")
fun provideBar(foobar: FooBar): Bar = foobar
Yes, it is slightly more declarative work, but also more clean IMHO.
from magnet.
(if Foo and Bar are interfaces, what they should be)
This case is very specific, but sometimes there is no better way around. The typical one I came across was when I wanted to implement an extension interface (e.g. PlayerFeature
) and the implementation of this interface wanted to hook up into another extensible thing thought another extension interface (e.g. PlayerListener
). In this case Manget must ensure that exactly the same instance gets registered under two (or more) interfaces. Current version of Magnet offers the following syntax for it:
@Instance(types = [PlayerFeature::class, PlayerListener::class])
internal class UndoPlayerFeature(): PlayerFeature, PlayerListener {
override fun onCustomAction(action: String, extras: Bundle?) // from PlayerFeature
override fun onPlayerEvent(event: PlayerEvent) // from PlayerListener
}
Recently I needed it when I was implementing ViewModel delegates, where ViewModel itself was implemented using predictable state container pattern. There were two interfaces like NextButtonDelegate
(or whatever other feature of the ViewModel) and Reducer<Change, State>
one, which hooked up into ViewModel's state reduce function. "Out of the box" support for such cases is a neat feature, in my opinion.
Why not do it like this?
It's surely possible, but I would not do it like that because
- Implementation class gets exposed to "outside" due to the first declaration, which is not always wanted.
- Magnet cannot guarantee, that the second and the third declarations return the same instance as the the first one, which is essential.
- Magnet will generate 3 factories instead of just one with aliases syntax.
- It has busier syntax and is harder to read. This is a very subjective opinion though.
Proposed change does not add a new feature but suppose rather remove an artificial restriction of the current syntax.
from magnet.
Understood your points, I guess it is just a very specific use case that is modeled in a rather general purpose tool, but no hard feelings here. Just from an API point of view I'd say that the additional (mental) complexity that an aliasing mechanism brings onto the table would have to be reasoned by more than one particular, very specific use case.
Like, you couldn't (or maybe you could, but would you?) prevent misuse of the feature like this, right?
@Instance(type = Foo::class, classifier = "foo")
@InstanceAlias(type = Foo::class, classifier = "bar")
internal class Foo() {}
But again, no hard feelings :)
from magnet.
The more I use Magnet and apply interface segregation principle, the often I need this feature. I might be biased, but I see it as an advantage having this kind of syntax under my fingers then going chatty dagger way.
Like, you couldn't (or maybe you could, but would you?) prevent misuse of the feature like this, right?
My gut feeling tells this is not a misuse, but I cannot say anything certain about it. It needs to be tried out. If this syntax/concept causes issues, it can always be deprecated and replaced by a better one.
from magnet.
Postponed until there is a real need for it.
from magnet.
Related Issues (20)
- Unsupported KotlinClassMetadata of type null after update to Kotlin 1.5.20 HOT 1
- Provide SavedStateRegistryOwner in a magnet.Factory interface HOT 5
- No stetho-enabled processes running - with Magnet 3.6-rc1 HOT 4
- java.lang.IllegalStateException: Single instance requested, while many instances are stored HOT 3
- Cannot verify type declaration HOT 1
- When release version 3.7 ? HOT 1
- Magnet for Kotlin 1.8. HOT 1
- Injection overrides HOT 15
- Lazy construction HOT 26
- Support default values in constructors and methods in Kotlin HOT 5
- Generics HOT 2
- Processor fails to generate Factory when custom scope name is used
- Lazy injection in Kotlin HOT 1
- Determine placement of instances HOT 16
- Implement scope visitor HOT 5
- 3.3-rc3 packaging issue HOT 6
- Wrong placement of instances when "getMany" and "sibling types" are used HOT 1
- Type binding HOT 17
- SelectorAttributeParser is treating nots as delimiters HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from magnet.