ybainier/Hypodermic

Resolution of single instances based on concrete and abstract types

Closed this issue · 3 comments

Greetings, I'm using this container and am really quite happy with it. However, there is one quirk that I've found myself working around and I wonder if it's something that you would consider changing or if it's even possible.

I have some code that does the following:

Hypodermic::ContainerBuilder builder;

builder.registerType<ConcreteClass>().as<InterfaceClass>().singleInstance();
...
auto container = builder.build();
...
auto singleton_interface_ref = container->resolve<InterfaceClass>();
auto singleton_concrete_ref = container->resolve<ConcreteClass>();

assert(singleton_interface_ref == singleton_concrete_ref); // Fails!

auto singleton_concrete_ref2 = container->resolve<ConcreteClass>();
assert(singleton_concrete_ref == singleton_concrete_ref2); // Passes

auto singleton_interface_ref2 = container->resolve<InterfaceClass>();
assert(singleton_interface_ref == singleton_interface_ref2); // Passes

Is it possible to have Hypodermic resolve the same reference regardless of whether you resolve the type ConcreteClass or InterfaceClass? My actual use-case is more layered than this, but I thought I'd start out with an illustrative example to see if it was even possible.

Thanks!

I’m using a fairly substantial modification of Hypodermic (for supporting Unreal Engine types) and I added a block for such resolutions. Basically anything registered with an alias will refuse to resolve the actual type unless asSelf() has also been used.

The rewrite makes it a bit tricky to supply a patch but it basically tracks any aliased types and rejects them in resolveIfCanBeRegistered, which is where the concrete type otherwise would be doubly registered.

I’m currently on vacation but I can supply more details in August.

@badiozam hey, as @judgeaxl stated, you can use asSelf() on a registration to tell Hypodermic that you want your concrete type to be resolvable as well. So if I use your sample it goes like this:

Hypodermic::ContainerBuilder builder;

builder.registerType< ConcreteClass >().as< InterfaceClass >().asSelf().singleInstance();
...
auto container = builder.build();
...
auto singleton_interface_ref = container->resolve< InterfaceClass >();
auto singleton_concrete_ref = container->resolve< ConcreteClass >();

assert(singleton_interface_ref == singleton_concrete_ref); // Will pass

You can have a look at the wiki to discover more features.

Cheers

@badiozam I am closing this issue. Feel free to keep asking for help.