public ContainerService Instantiate(Type type, bool crearteNew, IObjectAccessor arguments)
 {
     var builder = new ContainerService.Builder(type, this, crearteNew, arguments);
     if (builder.Status != ServiceStatus.Ok)
         return builder.Build();
     var declaredName = builder.GetDeclaredName();
     if (!constructingServices.Add(declaredName))
     {
         var previous = GetTopBuilder();
         if (previous == null)
             throw new InvalidOperationException(string.Format("assertion failure, service [{0}]", declaredName));
         var message = string.Format("cyclic dependency {0}{1} -> {0}",
             type.FormatName(), previous.Type == type ? "" : " ...-> " + previous.Type.FormatName());
         var cycleBuilder = new ContainerService.Builder(type, this, false, null);
         cycleBuilder.SetError(message);
         return cycleBuilder.Build();
     }
     stack.Add(builder);
     var expandResult = TryExpandUnions(Container.Configuration);
     if (expandResult != null)
     {
         var poppedContracts = Contracts.PopMany(expandResult.Length);
         foreach (var c in expandResult.CartesianProduct())
         {
             var childService = Resolve(new ServiceName(builder.Type, c));
             builder.LinkTo(Container.containerContext, childService, null);
             if (builder.Status.IsBad())
                 break;
         }
         Contracts.AddRange(poppedContracts);
     }
     else
         Container.Instantiate(builder);
     stack.RemoveLast();
     constructingServices.Remove(declaredName);
     return builder.Build();
 }
 public ContainerService Resolve(ServiceName name)
 {
     if (name.Contracts.Length == 0)
         return Container.ResolveSingleton(name.Type, this);
     var pushedCount = 0;
     foreach (var newContract in name.Contracts)
     {
         foreach (var c in Contracts)
             if (newContract.EqualsIgnoringCase(c))
             {
                 var resultBuilder = new ContainerService.Builder(name.Type, this, false, null);
                 const string messageFormat = "contract [{0}] already declared, all declared contracts [{1}]";
                 resultBuilder.SetError(string.Format(messageFormat, newContract, InternalHelpers.FormatContractsKey(Contracts)));
                 Contracts.RemoveLast(pushedCount);
                 return resultBuilder.Build();
             }
         Contracts.Add(newContract);
         pushedCount++;
     }
     var result = Container.ResolveSingleton(name.Type, this);
     Contracts.RemoveLast(name.Contracts.Length);
     return result;
 }
        internal ServiceDependency InstantiateDependency(ParameterInfo formalParameter, ContainerService.Builder builder)
        {
            ValueWithType actualArgument;
            if (builder.Arguments != null && builder.Arguments.TryGet(formalParameter.Name, out actualArgument))
                return ServiceDependency.Constant(formalParameter, actualArgument.value);
            var parameters = builder.Configuration.ParametersSource;
            object actualParameter;
            if (parameters != null && parameters.TryGet(formalParameter.Name, formalParameter.ParameterType, out actualParameter))
                return ServiceDependency.Constant(formalParameter, actualParameter);
            var dependencyConfiguration = builder.Configuration.GetOrNull(formalParameter);
            Type implementationType = null;
            if (dependencyConfiguration != null)
            {
                if (dependencyConfiguration.ValueAssigned)
                    return ServiceDependency.Constant(formalParameter, dependencyConfiguration.Value);
                if (dependencyConfiguration.Factory != null)
                {
                    var dependencyBuilder = new ContainerService.Builder(formalParameter.ParameterType, builder.Context, false, null);
                    dependencyBuilder.CreateInstanceBy(() => dependencyConfiguration.Factory(this), true);
                    return dependencyBuilder.Build().AsSingleInstanceDependency(formalParameter.Name);
                }
                implementationType = dependencyConfiguration.ImplementationType;
            }
            implementationType = implementationType ?? formalParameter.ParameterType;
            FromResourceAttribute resourceAttribute;
            if (implementationType == typeof (Stream) && formalParameter.TryGetCustomAttribute(out resourceAttribute))
            {
                var resourceStream = builder.Type.Assembly.GetManifestResourceStream(builder.Type, resourceAttribute.Name);
                if (resourceStream == null)
                    return ServiceDependency.Error(null, formalParameter.Name,
                        "can't find resource [{0}] in namespace of [{1}], assembly [{2}]",
                        resourceAttribute.Name, builder.Type, builder.Type.Assembly.GetName().Name);
                return ServiceDependency.Resource(formalParameter, resourceAttribute.Name, resourceStream);
            }
            var dependencyName = ServiceName.Parse(implementationType.UnwrapEnumerable(), false,
                InternalHelpers.ParseContracts(formalParameter));

            ServiceConfiguration interfaceConfiguration;
            try
            {
                interfaceConfiguration = GetConfiguration(dependencyName.Type, builder.Context);
            }
            catch (Exception e)
            {
                var dependencyService = new ContainerService.Builder(dependencyName.Type, builder.Context, false, null);
                dependencyService.SetError(e);
                return ServiceDependency.ServiceError(dependencyService.Build());
            }
            if (interfaceConfiguration.FactoryWithTarget != null)
                dependencyName = dependencyName.AddContracts(builder.Type.FormatName());
            if (dependencyName.Type.IsSimpleType())
            {
                if (!formalParameter.HasDefaultValue)
                    return ServiceDependency.Error(null, formalParameter.Name,
                        "parameter [{0}] of service [{1}] is not configured",
                        formalParameter.Name, builder.Type.FormatName());
                return ServiceDependency.Constant(formalParameter, formalParameter.DefaultValue);
            }
            var resultService = builder.Context.Resolve(dependencyName);
            if (resultService.Status.IsBad())
                return ServiceDependency.ServiceError(resultService);
            var isEnumerable = dependencyName.Type != implementationType;
            if (isEnumerable)
                return ServiceDependency.Service(resultService, resultService.GetAllValues(containerContext));
            if (resultService.Status == ServiceStatus.NotResolved)
            {
                if (formalParameter.HasDefaultValue)
                    return ServiceDependency.Service(resultService, formalParameter.DefaultValue);
                if (formalParameter.IsDefined<OptionalAttribute>() || formalParameter.IsDefined("CanBeNullAttribute"))
                    return ServiceDependency.Service(resultService, null);
                return ServiceDependency.NotResolved(resultService);
            }
            return resultService.AsSingleInstanceDependency(null);
        }