-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: Add by Type, GetByType and GetManyByType #30
Comments
Hello, I haven't fully checked your solution but here my first impressions. You added In the current version of the library, there are mainly two fields with that purpose: type TagFilterer struct{/* to be determined */}
// just after building the container
t := &TagFilterer{}
t.registerDefs(ctn.Definitions())
// later when you want to use the objects
names := t.GetDefNamesForType(instanceWithWantedType)
for _, name := range names {
obj := ctn.Get(name).(instanceWithWantedType)
} The The difficulties of this solution would be to define the role of the Another thing with your solution is that the name is not required if you provide a type. I think that if the tag system is improved in such a way that it is easy to find a definition without knowing its name, changing the behavior of the library to generate a random name (like Anyway, thank you for trying to improve the library. |
I do upfront validation of Type and ImplementedTypes during the I think no matter what the final library path takes an upfront validation like this is needed. Absolutely your suggestions will work, and I would like to help get it there. As for the GetManyByType and GetByType: The important thing here is that the LAST item of a type added is what gets returned by GetByType. So, something like In one of my examples, I add early in the flow an I am finding that now that I have type, I use it for everything when retrieving the objects. So, for me, everything is by type and hence TagFilterer would just support type. BTW: I don't use reflection after the Build happens because the Build produces reflect.Type lookup maps, so it should be as fast as what you have with the name lookups. |
I thought about it again. It still think tags are the way to go and I don't want to make a lot of changes to the library. To make tag more powerful, a new field type Tag struct {
Name string
Args map[string]string
Data interface{}
} In addition to that change definitions would:
That would be the only changes to the library. All the changes you implemented would have to be in another repository working as an extension of the main library. That would be used like this: typeManager := &ditypes.Manager{}
builder, _ := di.NewBuilder()
builder.Add(di.Def{
Build: func(ctn di.Container) (interface{}, error) {
return &MyObject{}, nil
},
Tags: []Tag{
{
Data: ditypes.TagData{
Type: reflect.TypeOf(&MyObject{}),
Implements: []reflect.Type{},
},
},
},
})
builder.set("typeManager", typeManager)
ctn := builder.Build()
orderedDefs := di.DefMap(ctn.Definitions()).SortedDefs()
err := typeManager.Register(orderedDefs)
// then in the request for example
typeManager := di.Get(r, "typeManager").(*ditypes.Manager)
di.Get(r, typeManager.FirstName(ditypes.Opts{
Is: reflect.TypeOf(&MyObject{})
})) In the documentation there would be a new part about tags (they are not documented yet) linking to the type extension. This is more or less what I suggested last time, but the |
Just the support for tags and a func to get a slice of all services which has the tag would be enough for me. |
Hello, I rewrote the entire library 4 months ago, but I have been too lazy to write the new README. |
First off, nice library. I was able to add these features and not have to rearchitect anything in the original library. My version is located here
If you accept these features, I can do a proper fork and PR so you can see how I did it.
New Features
The following are non breaking changes to sarulabs/di.
SafeGetByType
GetByType
SafeGetManyByType
GetManyByType
Just like dotnetcore, I would like to register a bunch of services that all implement the same interface. I would like to get back an array of all registered objects, and to do that I need to ask for them by type
For efficiency, type validation is done during registration. After that it should just be lookups.
When you do a
GetByType
, don't keep calling reflect to get a type of what is a compliled type. do it once and put it in a map.Registration
type DEF struct
Two new fields where added to the Def struct.
Type
: is the type of the object being registered.ImplementedTypes
: is the types that this object either is or implementsOnly the
Type
option is needed to register and it is automatically added as an implemented type. TheImplementedTypes
option is primarily for claiming that the added type supports a given set of interfaces. If this option is added, the originalType
is automatically added to theImplementedTypes
set.The following code will return an error if the added type DOES NOT implemented the
ImplementedTypes
that were claimed.Retrieval
The text was updated successfully, but these errors were encountered: