예제 #1
0
 internal ServiceDependency InstantiateDependency(ParameterInfo formalParameter, ContainerService.Builder builder)
 {
     ValueWithType actualArgument;
     if (builder.Arguments != null && builder.Arguments.TryGet(formalParameter.Name, out actualArgument))
         return containerContext.Constant(formalParameter, actualArgument.value);
     var parameters = builder.Configuration.ParametersSource;
     object actualParameter;
     if (parameters != null && parameters.TryGet(formalParameter.Name, formalParameter.ParameterType, out actualParameter))
         return containerContext.Constant(formalParameter, actualParameter);
     var dependencyConfiguration = builder.Configuration.GetOrNull(formalParameter);
     Type implementationType = null;
     if (dependencyConfiguration != null)
     {
         if (dependencyConfiguration.ValueAssigned)
             return containerContext.Constant(formalParameter, dependencyConfiguration.Value);
         if (dependencyConfiguration.Factory != null)
         {
             var dependencyBuilder = new ContainerService.Builder(new ServiceName(formalParameter.ParameterType))
             {
                 Context = builder.Context,
                 DependencyName = formalParameter.Name
             };
             builder.Context.Stack.Add(dependencyBuilder);
             dependencyBuilder.CreateInstanceBy(CallTarget.F(dependencyConfiguration.Factory), true);
             builder.Context.Stack.RemoveLast();
             return dependencyBuilder.GetService().AsDependency(containerContext, formalParameter.Name, false);
         }
         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 containerContext.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 containerContext.Resource(formalParameter, resourceAttribute.Name, resourceStream);
     }
     var dependencyName = ServiceName.Parse(implementationType.UnwrapEnumerable(),
         InternalHelpers.ParseContracts(formalParameter));
     if (dependencyName.Type.IsSimpleType())
     {
         if (!formalParameter.HasDefaultValue)
             return containerContext.Error(null, formalParameter.Name,
                 "parameter [{0}] of service [{1}] is not configured",
                 formalParameter.Name, builder.Type.FormatName());
         return containerContext.Constant(formalParameter, formalParameter.DefaultValue);
     }
     var resultService = ResolveCore(dependencyName, false, null, builder.Context);
     if (resultService.Status.IsBad())
         return containerContext.ServiceError(resultService);
     var isEnumerable = dependencyName.Type != implementationType;
     if (isEnumerable)
         return containerContext.Service(resultService, resultService.GetAllValues());
     if (resultService.Status == ServiceStatus.NotResolved)
     {
         if (formalParameter.HasDefaultValue)
             return containerContext.Service(resultService, formalParameter.DefaultValue);
         if (formalParameter.IsDefined<OptionalAttribute>() || formalParameter.IsDefined("CanBeNullAttribute"))
             return containerContext.Service(resultService, null);
         return containerContext.NotResolved(resultService);
     }
     return resultService.AsDependency(containerContext, null, false);
 }