Exemplo n.º 1
0
 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);
 }