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; }