ModelBuilder.DefaultExecuteStrategy.Build C# (CSharp) Method

Build() protected method

Builds an instance of the specified type.
The parameter is null. The parameter can not be created using this strategy.
protected Build ( Type type, string referenceName, object context ) : object
type System.Type The type of instance to create.
referenceName string Identifies the possible parameter or property name this value is intended for.
context object The possible context object this value is being created for.
return object
        protected virtual object Build(Type type, string referenceName, object context, params object[] args)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            EnsureInitialized();

            var circularReference = BuildChain.FirstOrDefault(x => x.GetType() == type);

            if (circularReference != null)
            {
                Log.CircularReferenceDetected(type);

                return circularReference;
            }

            Func<Type, string, LinkedList<object>, object> generator = null;
            Type generatorType = null;
            var contextType = context?.GetType();
            Type targetType = null;

            // First check if there is a creation rule
            var creationRule =
                Configuration.CreationRules?.Where(x => x.IsMatch(contextType, referenceName))
                    .OrderByDescending(x => x.Priority)
                    .FirstOrDefault();

            if (creationRule != null)
            {
                generator = creationRule.Create;
                generatorType = creationRule.GetType();

                // The creation rule is targeted against the type that owns the reference
                targetType = contextType;
            }
            else
            {
                // Next check if this is a type supported by a value generator
                var valueGenerator =
                    Configuration.ValueGenerators?.Where(x => x.IsSupported(type, referenceName, BuildChain))
                        .OrderByDescending(x => x.Priority)
                        .FirstOrDefault();

                if (valueGenerator != null)
                {
                    generator = valueGenerator.Generate;
                    generatorType = valueGenerator.GetType();

                    // The value generator is targeted against the type of the reference being generated for
                    targetType = type;
                }
            }

            if (generator != null)
            {
                Log.CreatingValue(type, context);

                try
                {
                    return generator(targetType, referenceName, BuildChain);
                }
                catch (BuildException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    Log.BuildFailure(ex);

                    const string MessageFormat =
                        "Failed to create value for type {0} using value generator {1}, {2}: {3}{4}{4}At the time of the failure, the build log was:{4}{4}{5}";
                    var buildLog = Log.Output;
                    var message = string.Format(
                        CultureInfo.CurrentCulture,
                        MessageFormat,
                        type.FullName,
                        generatorType.FullName,
                        ex.GetType().Name,
                        ex.Message,
                        Environment.NewLine,
                        buildLog);

                    throw new BuildException(message, type, referenceName, context, buildLog, ex);
                }
            }

            var typeCreator =
                Configuration.TypeCreators?.Where(x => x.CanCreate(type, referenceName, BuildChain))
                    .OrderByDescending(x => x.Priority)
                    .FirstOrDefault();

            if (typeCreator == null)
            {
                throw BuildFailureException(type, referenceName, context);
            }

            Log.CreatingType(type, context);

            try
            {
                var instance = CreateAndPopulate(type, referenceName, BuildChain, args, typeCreator);

                return instance;
            }
            catch (BuildException)
            {
                // Don't recapture build failures here
                throw;
            }
            catch (Exception ex)
            {
                Log.BuildFailure(ex);

                const string MessageFormat =
                    "Failed to create type {0} using type creator {1}, {2}: {3}{4}{4}At the time of the failure, the build log was:{4}{4}{5}";
                var buildLog = Log.Output;
                var message = string.Format(
                    CultureInfo.CurrentCulture,
                    MessageFormat,
                    type.FullName,
                    typeCreator.GetType().FullName,
                    ex.GetType().Name,
                    ex.Message,
                    Environment.NewLine,
                    buildLog);

                throw new BuildException(message, type, referenceName, context, buildLog, ex);
            }
            finally
            {
                Log.CreatedType(type, context);
            }
        }