public Builder(Type type, ResolutionContext context, bool createNew, IObjectAccessor arguments)
 {
     Arguments = arguments;
     CreateNew = createNew;
     target = new ContainerService {Type = type};
     Context = context;
     DeclaredContracts = context.Contracts.ToArray();
     try
     {
         Configuration = context.Container.GetConfiguration(Type, context);
     }
     catch (Exception e)
     {
         SetError(e);
         return;
     }
     SetComment(Configuration.Comment);
     foreach (var contract in Configuration.Contracts)
     {
         if (usedContractNames == null)
             usedContractNames = new List<string>();
         if (!usedContractNames.Contains(contract, StringComparer.OrdinalIgnoreCase))
             usedContractNames.Add(contract);
     }
 }
 public static void Pop(ResolutionContextActivation activation)
 {
     current = activation.previous;
 }
 public static ResolutionContextActivation Push(SimpleContainer container)
 {
     var prev = current;
     return new ResolutionContextActivation
     {
         activated = prev != null && prev.Container == container
             ? prev
             : current = new ResolutionContext
             {
                 Container = container,
                 prev = prev,
                 Stack = new List<ContainerService.Builder>(),
                 ConstructingServices = new HashSet<ServiceName>(),
                 Contracts = new ContractsList(),
                 AnalizeDependenciesOnly = prev != null && prev.AnalizeDependenciesOnly
             },
         previous = prev
     };
 }
 private void PopResolutionContext(ResolutionContext.ResolutionContextActivation activation,
     ContainerService containerService, bool isEnumerable)
 {
     ResolutionContext.Pop(activation);
     if (activation.previous == null)
         return;
     var resultDependency = containerService.AsDependency(containerContext, "() => " + containerService.Type.FormatName(),isEnumerable);
     if (activation.activated.Container != activation.previous.Container)
         resultDependency.Comment = "container boundary";
     activation.previous.TopBuilder.AddDependency(resultDependency, false);
 }
        internal ContainerService ResolveCore(ServiceName name, bool createNew, IObjectAccessor arguments, ResolutionContext context)
        {
            var pushedContracts = context.Contracts.Push(name.Contracts);
            var declaredName = new ServiceName(name.Type, context.Contracts.Snapshot());
            if (context.HasCycle(declaredName))
            {
                var message = string.Format("cyclic dependency for service [{0}], stack\r\n{1}",
                    declaredName.Type.FormatName(), context.FormatStack() + "\r\n\t" + declaredName);
                context.Contracts.RemoveLast(pushedContracts.pushedContractsCount);
                return ContainerService.Error(declaredName, message);
            }
            if (!pushedContracts.isOk)
            {
                const string messageFormat = "contract [{0}] already declared, stack\r\n{1}";
                var message = string.Format(messageFormat, pushedContracts.duplicatedContractName,
                    context.FormatStack() + "\r\n\t" + name);
                context.Contracts.RemoveLast(pushedContracts.pushedContractsCount);
                return ContainerService.Error(name, message);
            }
            context.ConstructingServices.Add(declaredName);

            ServiceConfiguration configuration = null;
            Exception configurationException = null;
            try
            {
                configuration = GetConfiguration(declaredName.Type, context);
            }
            catch (Exception e)
            {
                configurationException = e;
            }
            var actualName = configuration != null && configuration.FactoryDependsOnTarget && context.Stack.Count > 0
                ? declaredName.AddContracts(context.TopBuilder.Type.FormatName())
                : declaredName;
            ContainerServiceId id = null;
            if (!createNew)
            {
                id = instanceCache.GetOrAdd(actualName, createId);
                var acquireResult = id.AcquireInstantiateLock();
                if (!acquireResult.acquired)
                {
                    context.ConstructingServices.Remove(declaredName);
                    context.Contracts.RemoveLast(pushedContracts.pushedContractsCount);
                    return acquireResult.alreadyConstructedService;
                }
            }
            var builder = new ContainerService.Builder(actualName);
            context.Stack.Add(builder);
            builder.Context = context;
            builder.DeclaredContracts = actualName.Contracts;
            if (configuration == null)
                builder.SetError(configurationException);
            else
            {
                builder.SetConfiguration(configuration);
                builder.ExpandedUnions = context.Contracts.TryExpandUnions(Configuration);
                if (builder.ExpandedUnions.HasValue)
                {
                    var poppedContracts = context.Contracts.PopMany(builder.ExpandedUnions.Value.contracts.Length);
                    foreach (var c in builder.ExpandedUnions.Value.contracts.CartesianProduct())
                    {
                        var childService = ResolveCore(new ServiceName(name.Type, c), createNew, arguments, context);
                        builder.LinkTo(containerContext, childService, null);
                        if (builder.Status.IsBad())
                            break;
                    }
                    context.Contracts.PushNoCheck(poppedContracts);
                }
                else
                {
                    builder.CreateNew = createNew;
                    builder.Arguments = arguments;
                    Instantiate(builder);
                }
            }
            context.ConstructingServices.Remove(declaredName);
            context.Contracts.RemoveLast(pushedContracts.pushedContractsCount);
            context.Stack.RemoveLast();
            var result = builder.GetService();
            if (id != null)
                id.ReleaseInstantiateLock(builder.Context.AnalizeDependenciesOnly ? null : result);
            return result;
        }
 internal ServiceConfiguration GetConfiguration(Type type, ResolutionContext context)
 {
     return GetConfigurationOrNull(type, context.Contracts) ?? ServiceConfiguration.empty;
 }
 public object Create(Type type, IEnumerable<string> contracts, object arguments)
 {
     EnsureNotDisposed();
     if (type == null)
         throw new ArgumentNullException("type");
     var name = CreateServiceName(type, contracts);
     Func<object> compiledFactory;
     if (arguments == null && factoryCache.TryGetValue(name, out compiledFactory))
         return compiledFactory();
     var context = new ResolutionContext(this, name.Contracts);
     var result = context.Create(type, null, arguments);
     result.EnsureInitialized(containerContext, result);
     return result.GetSingleValue(containerContext, false, null);
 }
 internal ContainerService ResolveSingleton(Type type, ResolutionContext context)
 {
     var name = new ServiceName(type, context.Contracts.ToArray());
     var id = instanceCache.GetOrAdd(name, createId);
     ContainerService result;
     if (!id.AcquireInstantiateLock(out result))
         return result;
     result = context.Instantiate(type, false, null);
     id.ReleaseInstantiateLock(context.AnalizeDependenciesOnly ? null : result);
     return result;
 }