Tagged services
Blacksmoke16 opened this issue · 0 comments
Blacksmoke16 commented
Hey, first off, this is my new favorite shard. I had a feature request that would make it even better; the ability to tag services. For example
class FeedPartner
include DI::Taggable
getter id : String
getter name : String
def initialize(@id : String, @name : String); end
end
module Container
include DI::ContainerMixin
register FeedPartner, FeedPartner.new("GOOGLE", "Google"), tag: "feed_partner"
register FeedPartner, FeedPartner.new("FACEBOOK", "Facebook"), tag: "feed_partner"
end
partners = Container.tagged "feed_partner" # => # => [#<FeedPartner:0x7f0f7891bd00 @id="GOOGLE", @name="Google">, #<FeedPartner:0x7f0f7891bcc0 @id="FACEBOOK", @name="Google">]
My current idea to implement this would be to define a module like DI::Taggable
that can be included into types that the user wants to be able to be tagged.
Then the ContainerMixin could define a hash like @@services = Hash(String, Array(DI::Taggable)).new
, where upon adding a resolve method, add that value to hash for the given tag.
\{% if type.resolve < DI::Taggable %}
@@services[\{{tag}}] = Array(DI::Taggable).new unless @@services.has_key? \{{tag}}
@@services[\{{tag}}] << \{{value}}.as(\{{type}})
\{% end %}
Finally, implement a method to get services based on tag:
def self.tagged(tag : String)
@@services[tag]? || [] of DI::Taggable
end
I currently have this working on my fork, however I wanted to get your thoughts before making a PR.