If you changed the registration to the following:
container.RegisterType(typeof(IFooDerived1), typeof(Foo), new ContainerControlledLifetimeManager()); container.RegisterType(typeof(IFooDerived2), typeof(Foo), new TransientLifetimeManager()); container.RegisterType(typeof(IFoo), typeof(Foo), new ExternallyControlledLifetimeManager());
You will get the following result:
IFoo -> Foo : ExternallyControlledLifetimeManager IFooDerived1 -> Foo : ExternallyControlledLifetimeManager IFooDerived2 -> Foo : ExternallyControlledLifetimeManager
Wat? No matter what abstraction you extract, you will always have the same instance. Therefore, changing the order of registration, you get a completely different behavior in lifestyle.
btw, ExternallyControlledLifetimeManager scary like fuck because it uses a weak reference to the object and can recreate it after the application no longer stores the reference to It. You are unlikely to ever use this lifestyle.
I'm trying to figure this out, but it seems that in Unity, when you do the registration, you are actually registering an implementation with a certain lifestyle, and the provided abstraction just matches that registration. Therefore, if we define an alternative API for Unity, the registration will be something like this:
MakeEntry(typeof(Foo), new ExternallyControlledLifetimeManager()); MapToEntry(from: typeof(IFoo), to: typeof(Foo));
So, with the help of this "alternative" API, it becomes clearer that the following happens:
MakeEntry(typeof(Foo), new ExternallyControlledLifetimeManager()); MapToEntry(from: typeof(IFoo), to: typeof(Foo)); MakeEntry(typeof(Foo), new ExternallyControlledLifetimeManager()); MapToEntry(from: typeof(IFooDerived1), to: typeof(Foo)); MakeEntry(typeof(Foo), new TransientLifetimeManager()); MapToEntry(from: typeof(IFooDerived2), to: typeof(Foo));
This means that there are three entries for the same Foo , and apparently Unity just accepts this silence, and the latter wins. Don't you hate this implicit behavior?
Can I switch to another library?