private bool GetTaskFactory()

in src/Build/Instance/TaskRegistry.cs [1228:1424]


            private bool GetTaskFactory(TargetLoggingContext targetLoggingContext, ElementLocation elementLocation, string taskProjectFile)
            {
                // see if we have already created the factory before, only create it once
                if (_taskFactoryWrapperInstance == null)
                {
                    AssemblyLoadInfo taskFactoryLoadInfo = TaskFactoryAssemblyLoadInfo;
                    ErrorUtilities.VerifyThrow(taskFactoryLoadInfo != null, "TaskFactoryLoadInfo should never be null");
                    ITaskFactory factory = null;
                    LoadedType loadedType = null;


                    bool isAssemblyTaskFactory = String.Equals(TaskFactoryAttributeName, AssemblyTaskFactory, StringComparison.OrdinalIgnoreCase);
                    bool isTaskHostFactory = String.Equals(TaskFactoryAttributeName, TaskHostFactory, StringComparison.OrdinalIgnoreCase);

                    if (isAssemblyTaskFactory || isTaskHostFactory)
                    {
                        bool explicitlyLaunchTaskHost =
                            isTaskHostFactory ||
                            (
                                s_forceTaskHostLaunch &&
                                !TypeLoader.IsPartialTypeNameMatch(RegisteredName, "MSBuild") &&
                                !TypeLoader.IsPartialTypeNameMatch(RegisteredName, "CallTarget")
                            );

                        // Create an instance of the internal assembly task factory, it has the error handling built into its methods.
                        AssemblyTaskFactory taskFactory = new AssemblyTaskFactory();
                        loadedType = taskFactory.InitializeFactory(taskFactoryLoadInfo, RegisteredName, ParameterGroupAndTaskBody.UsingTaskParameters, ParameterGroupAndTaskBody.InlineTaskXmlBody, TaskFactoryParameters, explicitlyLaunchTaskHost, targetLoggingContext, elementLocation, taskProjectFile);
                        factory = taskFactory;
                    }
                    else
                    {
                        // We are not one of the default factories. 
                        TaskEngineAssemblyResolver resolver = null;

                        try
                        {
                            // Add a resolver to allow us to resolve types from the assembly when loading into the current appdomain.
                            resolver = new TaskEngineAssemblyResolver();
                            resolver.Initialize(taskFactoryLoadInfo.AssemblyFile);
                            resolver.InstallHandler();

                            try
                            {
                                lock (s_taskFactoryTypeLoaderLock)
                                {
                                    if (s_taskFactoryTypeLoader == null)
                                    {
                                        s_taskFactoryTypeLoader = new TypeLoader(s_taskFactoryTypeFilter);
                                    }
                                }

                                // Make sure we only look for task factory classes when loading based on the name
                                loadedType = s_taskFactoryTypeLoader.Load(TaskFactoryAttributeName, taskFactoryLoadInfo);

                                if (loadedType == null)
                                {
                                    // We could not find the type (this is what null means from the Load method) but there is no reason given so we can only log the fact that 
                                    // we could not find the name given in the task factory attribute in the class specified in the assembly File or assemblyName fields.
                                    ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "CouldNotFindFactory", TaskFactoryAttributeName, taskFactoryLoadInfo.AssemblyLocation);
                                }

                                targetLoggingContext.LogComment(MessageImportance.Low, "InitializingTaskFactory", TaskFactoryAttributeName, taskFactoryLoadInfo.AssemblyLocation);
                            }
                            catch (TargetInvocationException e)
                            {
                                // Exception thrown by the called code itself
                                // Log the stack, so the task vendor can fix their code
                                ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskFactoryLoadFailure", TaskFactoryAttributeName, taskFactoryLoadInfo.AssemblyLocation, Environment.NewLine + e.InnerException.ToString());
                            }
                            catch (ReflectionTypeLoadException e)
                            {
                                // ReflectionTypeLoadException.LoaderExceptions may contain nulls
                                foreach (Exception exception in e.LoaderExceptions)
                                {
                                    if (exception != null)
                                    {
                                        targetLoggingContext.LogError(new BuildEventFileInfo(taskProjectFile), "TaskFactoryLoadFailure", TaskFactoryAttributeName, taskFactoryLoadInfo.AssemblyLocation, exception.Message);
                                    }
                                }

                                ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskFactoryLoadFailure", TaskFactoryAttributeName, taskFactoryLoadInfo.AssemblyLocation, e.Message);
                            }
                            catch (Exception e) // Catching Exception, but rethrowing unless it's a well-known exception.
                            {
                                if (ExceptionHandling.NotExpectedReflectionException(e))
                                {
                                    throw;
                                }

                                ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskFactoryLoadFailure", TaskFactoryAttributeName, taskFactoryLoadInfo.AssemblyLocation, e.Message);
                            }

                            try
                            {
                                // We have loaded the type, lets now try and construct it
                                // Any exceptions from the constructor of the task factory will be caught lower down and turned into an InvalidProjectFileExceptions
#if FEATURE_APPDOMAIN
                                factory = (ITaskFactory)AppDomain.CurrentDomain.CreateInstanceAndUnwrap(loadedType.Type.GetTypeInfo().Assembly.FullName, loadedType.Type.FullName);
#else
                                factory = (ITaskFactory) Activator.CreateInstance(loadedType.Type);
#endif
                                TaskFactoryLoggingHost taskFactoryLoggingHost = new TaskFactoryLoggingHost(true /*I dont have the data at this point, the safest thing to do is make sure events are serializable*/, elementLocation, targetLoggingContext);

                                bool initialized = false;
                                try
                                {
                                    ITaskFactory2 factory2 = factory as ITaskFactory2;
                                    if (factory2 != null)
                                    {
                                        initialized = factory2.Initialize(RegisteredName, TaskFactoryParameters, ParameterGroupAndTaskBody.UsingTaskParameters, ParameterGroupAndTaskBody.InlineTaskXmlBody, taskFactoryLoggingHost);
                                    }
                                    else
                                    {
                                        initialized = factory.Initialize(RegisteredName, ParameterGroupAndTaskBody.UsingTaskParameters, ParameterGroupAndTaskBody.InlineTaskXmlBody, taskFactoryLoggingHost);

                                        // TaskFactoryParameters will always be null unless specifically created to have runtime and architecture parameters.
                                        if (TaskFactoryParameters != null)
                                        {
                                            targetLoggingContext.LogWarning
                                                (
                                                    new BuildEventFileInfo(elementLocation),
                                                    null,
                                                    "TaskFactoryWillIgnoreTaskFactoryParameters",
                                                    factory.FactoryName,
                                                    XMakeAttributes.runtime,
                                                    XMakeAttributes.architecture,
                                                    RegisteredName
                                                );
                                        }
                                    }
                                }
                                finally
                                {
#if FEATURE_APPDOMAIN
                                    taskFactoryLoggingHost.MarkAsInactive();
#endif
                                }

                                if (!initialized)
                                {
                                    _taskFactoryWrapperInstance = null;
                                    return false;
                                }
                            }
                            catch (InvalidCastException e)
                            {
                                string message = String.Empty;
#if DEBUG
                                message += UnhandledFactoryError;
#endif
                                message += e.Message;

                                // Could get an invalid cast when Creating Instance and UnWrap due to the framework assembly not being the same.
                                targetLoggingContext.LogError
                                (
                                    new BuildEventFileInfo(elementLocation.File, elementLocation.Line, elementLocation.Column),
                                    "TaskFactoryInstantiationFailureErrorInvalidCast",
                                    TaskFactoryAttributeName,
                                    taskFactoryLoadInfo.AssemblyLocation,
                                    message
                                );

                                return false;
                            }
                            catch (Exception e) // Catching Exception, but rethrowing unless it's a well-known exception.
                            {
                                if (ExceptionHandling.IsCriticalException(e))
                                {
                                    throw;
                                }

                                string message = String.Empty;
#if DEBUG
                                message += UnhandledFactoryError;
#endif
                                // message += e.ToString();
                                message += e.Message;

                                ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "TaskFactoryLoadFailure", TaskFactoryAttributeName, taskFactoryLoadInfo.AssemblyLocation, message);
                            }
                        }
                        finally
                        {
                            if (resolver != null)
                            {
                                resolver.RemoveHandler();
                                resolver = null;
                            }
                        }
                    }


                    _taskFactoryWrapperInstance = new TaskFactoryWrapper(factory, loadedType, RegisteredName, TaskFactoryParameters);
                }

                return true;
            }