Unable to use DI container names for different interfaces
// model generators
GlobalContainer.RegisterType<TDelphiModelGenerator>.
Implements<IModelGenerator>('Delphi').AsSingleton;
GlobalContainer.RegisterType<TCSharpModelGenerator>.
Implements<IModelGenerator>('CSharp').AsSingleton;
// language type converters
GlobalContainer.RegisterType<TLocalToDelphiTypeConverter>.
Implements<ILocalTypeToLanguageTypeConverter>('Delphi').AsSingleton;
GlobalContainer.RegisterType<TLocalToCSharpTypeConverter>.
Implements<ILocalTypeToLanguageTypeConverter>('CSharp').AsSingleton;
I receive a "Duplicate service name found" exception when registering the above classes. If you notice, I use the same names (Delphi and CSharp) but for different services (IModelGenerator and ILocalTypeToLanguageTypeConverter). I do not see why this is not supported.
Comments (16)
-
repo owner -
reporter Having used the framework for a while, i could tell this was not a bug. That's why I classified it as an enhancement. :)
Well if you look at my use-case, since I have already specified the interface in Implements<IInterface>, it feels most natural that the service name would be within the scope of the interface. Currently it has global scope, which seems to defeat the idea behind DI because now I suddenly need to know that this name is already in use somewhere else in the code.
This request will not break any existing code if you think about it. I don't have experience with Java Spring. If this is how it is implemented there, then so be it.
Thanks for all the effort you are putting into this project btw.
-
repo owner Luckily it does not matter how it is implemented in Java Spring. Spring4D is not related to them in any kind except a "similar" name. :)
And yes, changing this will break existing code. Just look at the example on stackoverflow I posted. With your proposal I could register two different interfaces with the same name that might share a common ancestor type. When I resolve this ancestor type I would get an error because the name is not unique.
However I will look into if it is possible by some extension.
-
reporter Well I did not know that they were not related, I tried to learn how to use S4D by searching for the Java documentation. Then I stumbled across the wiki on bitbucket which was pretty good enough to get me started.
Ancestors... I did not think of that. Which means that there is a lot more going under the covers than is perceptible to the untrained eye.
Thanks for your time.
-
repo owner - changed milestone to Future version
- edited description
-
repo owner - changed version to 1.1 (released)
-
repo owner - changed version to 1.1 (master)
-
repo owner - changed version to 1.1
-
repo owner - changed milestone to 1.3
-
assigned issue to
For version 1.3 I will work on some solution to make something like that available. It will follow a similar approach as Ninject's contextual binding
-
I looking for context and services today, you read my mind:) great
-
Hi! This enhacement would be nice. For example we publish data using interfaces, and there are different classes implementing the same interface. So maybe a class publishes the data throught sockets, another class throught the opensplice DDS bus, and so on... So somewhere we need to select dinamically each time the interface, and nowadays we do it with a 'name', for example: 'Sockets.Client', 'DDS', ...So if we want to register the different classes that implement an interface with its name, no problem...but when we need different interfaces to publish different information, we need to assign same names in the registration for different classes for different interfaces (I hope the explanation is clear). So we have a similar problem that the first comment. Thanks for your great work
-
reporter Thanks for the upvotes. :)
-
repo owner - edited description
- changed status to open
-
repo owner - changed milestone to 2.0
-
repo owner - changed milestone to 2.1
-
we have similar needs. As an option:
https://bitbucket.org/sglienke/spring4d/pull-requests/47 - Log in to comment
This is by design because every service needs to have a unique name. It needs to be unique because you can resolve just by name without knowing the exact type it was registered as. This is especially useful when you are resolving as a base type of the registered service type as shown here: http://stackoverflow.com/questions/22762478/how-to-get-child-interface-instance-from-servicelocator-in-spring4d