示例#1
0
        /// <inheritdoc />
        public IEnumerable <IToken> Apply(IMutableContainer container)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }
            var singletonLifetimeResolver          = container.GetResolver <ILifetime>(Lifetime.Singleton.AsTag());
            var containerSingletonLifetimeResolver = container.GetResolver <ILifetime>(Lifetime.ContainerSingleton.AsTag());
            var disposingLifetimeResolver          = container.GetResolver <ILifetime>(Lifetime.Disposing.AsTag());

            foreach (var serviceGroup in this.Reverse().Select((service, index) => new { index, item = service }).GroupBy(i => i.item.ServiceType))
            {
                var isFirst = true;
                foreach (var description in serviceGroup)
                {
                    var service = description.item;
                    var binding = container.Bind(service.ServiceType);
                    if (!isFirst)
                    {
                        binding = binding.Tag(description.index);
                    }
                    else
                    {
                        isFirst = false;
                    }

                    switch (service.Lifetime)
                    {
                    case ServiceLifetime.Transient:
                        binding = binding.Lifetime(disposingLifetimeResolver(container));
                        break;

                    case ServiceLifetime.Singleton:
                        binding = binding.Lifetime(singletonLifetimeResolver(container));
                        break;

                    case ServiceLifetime.Scoped:
                        binding = binding.Lifetime(containerSingletonLifetimeResolver(container));
                        break;

                    default:
                        throw new NotSupportedException($"Unknown lifetime {service.Lifetime}.");
                    }

                    if (service.ImplementationType != null)
                    {
                        yield return(binding.To(service.ImplementationType));

                        continue;
                    }

                    if (service.ImplementationFactory != null)
                    {
                        yield return(binding.To(ctx => service.ImplementationFactory(ctx.Container.Inject <IServiceProvider>())));

                        continue;
                    }

                    if (service.ImplementationInstance != null)
                    {
                        yield return(binding.To(ctx => service.ImplementationInstance));

                        continue;
                    }

                    throw new NotSupportedException($"The service descriptor {service} is not supported.");
                }
            }

            yield return(container
                         .Bind <IServiceProvider>().Bind <ISupportRequiredService>().Lifetime(singletonLifetimeResolver(container)).To <ServiceProvider>()
                         .Bind <IServiceScopeFactory>().Lifetime(singletonLifetimeResolver(container)).To <ServiceScopeFactory>()
                         .Bind <IServiceScope>().To <ServiceScope>()
                         // IEnumerable should preserve an order
                         .Bind <IEnumerable <TT> >().To(ctx => ctx.Container.Inject <IEnumerable <TT> >(TagKeyComparer.Shared, ctx.Args)));
        }