private void RegisterPropertyInjector(PropertyInjector injector)
        {
            var copy = this.propertyInjectorCache.MakeCopy();

            copy[injector.Type] = injector;

            // Prevent the compiler, JIT, and processor to reorder these statements to prevent the instance
            // producer from being added after the snapshot has been made accessible to other threads.
            Thread.MemoryBarrier();

            // Replace the original with the new version that includes the serviceType.
            this.propertyInjectorCache = copy;
        }
        public void InjectProperties(object instance)
        {
            Requires.IsNotNull(instance, "instance");

            PropertyInjector propertyInjector;

            if (!this.propertyInjectorCache.TryGetValue(instance.GetType(), out propertyInjector))
            {
                propertyInjector = new PropertyInjector(this, instance.GetType());

                this.RegisterPropertyInjector(propertyInjector);
            }

            propertyInjector.Inject(instance);
        }