public static bool TryCreate(ContainerService.Builder builder) { var factoryType = builder.Type.GetNestedType("Factory"); if (factoryType == null) return false; var method = factoryType.GetMethod("Create", Type.EmptyTypes); if (method == null) return false; var factory = builder.Context.Container.ResolveSingleton(method.DeclaringType, builder.Context); var dependency = factory.AsSingleInstanceDependency(null); builder.AddDependency(dependency, false); if (dependency.Status == ServiceStatus.Ok) builder.CreateInstance(method, dependency.Value, new object[0]); return true; }
private void InstantiateImplementation(ContainerService.Builder builder) { if (builder.DontUse()) { builder.SetComment("DontUse"); return; } var result = FactoryCreator.TryCreate(builder) ?? LazyCreator.TryCreate(builder); if (result != null) { builder.AddInstance(result, true); return; } if (NestedFactoryCreator.TryCreate(builder)) return; if (CtorFactoryCreator.TryCreate(builder)) return; if (builder.Type.IsDelegate()) { builder.SetError(string.Format("can't create delegate [{0}]", builder.Type.FormatName())); return; } var constructor = builder.Type.GetConstructor(); if (!constructor.isOk) { builder.SetError(constructor.errorMessage); return; } var formalParameters = constructor.value.GetParameters(); var actualArguments = new object[formalParameters.Length]; var hasServiceNameParameters = false; for (var i = 0; i < formalParameters.Length; i++) { var formalParameter = formalParameters[i]; if (formalParameter.ParameterType == typeof (ServiceName)) { hasServiceNameParameters = true; continue; } var dependency = InstantiateDependency(formalParameter, builder).CastTo(formalParameter.ParameterType); builder.AddDependency(dependency, false); if (dependency.ContainerService != null) builder.UnionUsedContracts(dependency.ContainerService); if (builder.Status != ServiceStatus.Ok && !builder.Context.AnalizeDependenciesOnly) return; actualArguments[i] = dependency.Value; } foreach (var d in builder.Configuration.ImplicitDependencies) { var dependency = builder.Context.Resolve(d).AsSingleInstanceDependency(null); dependency.Comment = "implicit"; builder.AddDependency(dependency, false); if (dependency.ContainerService != null) builder.UnionUsedContracts(dependency.ContainerService); if (builder.Status != ServiceStatus.Ok) return; } builder.EndResolveDependencies(); if (builder.Context.AnalizeDependenciesOnly) return; var dependenciesResolvedByArguments = builder.Arguments == null ? InternalHelpers.emptyStrings : builder.Arguments.GetUsed().Select(InternalHelpers.ByNameDependencyKey); var unusedConfigurationKeys = builder.Configuration.GetUnusedDependencyConfigurationKeys() .Except(dependenciesResolvedByArguments) .ToArray(); if (unusedConfigurationKeys.Length > 0) { builder.SetError(string.Format("unused dependency configurations [{0}]", unusedConfigurationKeys.JoinStrings(","))); return; } if (hasServiceNameParameters) for (var i = 0; i < formalParameters.Length; i++) if (formalParameters[i].ParameterType == typeof (ServiceName)) actualArguments[i] = builder.GetName(); if (builder.CreateNew || builder.DeclaredContracts.Length == builder.FinalUsedContracts.Length) { builder.CreateInstance(constructor.value, null, actualArguments); if (builder.CreateNew && builder.Arguments == null) { var compiledConstructor = constructor.value.Compile(); factoryCache.TryAdd(builder.GetName(), () => { var instance = compiledConstructor(null, actualArguments); var component = instance as IInitializable; if (component != null) component.Initialize(); return instance; }); } return; } var serviceForUsedContractsId = instanceCache.GetOrAdd(builder.GetName(), createId); ContainerService serviceForUsedContracts; if (serviceForUsedContractsId.AcquireInstantiateLock(out serviceForUsedContracts)) { builder.CreateInstance(constructor.value, null, actualArguments); serviceForUsedContracts = builder.Build(); serviceForUsedContractsId.ReleaseInstantiateLock(builder.Context.AnalizeDependenciesOnly ? null : serviceForUsedContracts); } else builder.Reuse(serviceForUsedContracts); }