When trying to resolve a type, most DI containers always look for a constructor with the maximum number of parameters. For this reason, the CachingService constructor (ObjectCache cache) was called by default. Because the ObjectCache instance is not registered with Unity, permission is not enforced. After you force a type to call a specific constructor, everything works.
So, if you register IAppCache and force it to call CachingService (), the constructor with a lower value, it will work as expected.
container.RegisterType<IAppCache, CachingService>(new InjectionConstructor());
By registering it this way, force the constructor to be called with fewer constructors and internally it will be discarded to what the third part library wants to use by default. In your case it will be
CachingService (): this is (MemoryCache.Default)
Another option that was mentioned in other answers is to register and pass the constructor parameter yourself.
container.RegisterType<IAppCache, CachingService>(new InjectionConstructor(MemoryCache.Default));
This will also work, but here you take the responsibility of providing the cache provider. In my opinion, I would prefer a third-party library to handle its own defaults instead of me when the consumer took on this responsibility.
Please look. How does Unity.Resolve know which constructor to use?
And some more info for Niject https://github.com/ninject/ninject/wiki/Injection-Patterns
If none of the constructors has an [Inject] attribute, Ninject will select one with most of the parameters that Ninject understands how to allow.