File: System\ServiceModel\Activation\WorkflowServiceHostFactory.cs
Project: ndp\cdf\src\NetFx35\System.WorkflowServices\System.WorkflowServices.csproj (System.WorkflowServices)
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Activation
{
    using System.Web;
    using System.Web.Hosting;
    using System.IO;
    using System.ServiceModel.Diagnostics;
    using System.Web.Compilation;
    using System.Reflection;
    using System.Workflow.Runtime;
    using System.Workflow.ComponentModel.Compiler;
    using System.Diagnostics;
 
    [Obsolete("The WF3 types are deprecated.  Instead, please use the new WF4 types from System.Activities.*")]
    public class WorkflowServiceHostFactory : ServiceHostFactoryBase
    {
        TypeProvider typeProvider;
 
        public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
        {
            WorkflowDefinitionContext workflowDefinitionContext = null;
 
            Stream workflowDefinitionStream = null;
            Stream ruleDefinitionStream = null;
 
            if (string.IsNullOrEmpty(constructorString))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.WorkflowServiceHostFactoryConstructorStringNotProvided)));
            }
 
            if (!HostingEnvironment.IsHosted)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.ProcessNotExecutingUnderHostedContext)));
            }
 
            Type workflowType = this.GetTypeFromString(constructorString, baseAddresses);
 
            if (workflowType != null)
            {
                workflowDefinitionContext = new CompiledWorkflowDefinitionContext(workflowType);
            }
            else
            {
                try
                {
                    IDisposable impersonationContext = null;
                    try
                    {
                        try
                        {
 
                        }
                        finally
                        {
                            //Ensure thread.Abort doesnt interfere b/w impersonate & assignment.
                            impersonationContext = HostingEnvironment.Impersonate();
                        }
 
                        string xomlVirtualPath = Path.Combine(AspNetEnvironment.Current.CurrentVirtualPath, constructorString);
 
                        if (HostingEnvironment.VirtualPathProvider.FileExists(xomlVirtualPath))
                        {
                            workflowDefinitionStream = HostingEnvironment.VirtualPathProvider.GetFile(xomlVirtualPath).Open();
                            string ruleFilePath = Path.ChangeExtension(xomlVirtualPath, WorkflowServiceBuildProvider.ruleFileExtension);
 
                            if (HostingEnvironment.VirtualPathProvider.FileExists(ruleFilePath))
                            {
                                ruleDefinitionStream = HostingEnvironment.VirtualPathProvider.GetFile(ruleFilePath).Open();
                                workflowDefinitionContext = new StreamedWorkflowDefinitionContext(workflowDefinitionStream, ruleDefinitionStream, this.typeProvider);
                            }
                            else
                            {
                                workflowDefinitionContext = new StreamedWorkflowDefinitionContext(workflowDefinitionStream, null, this.typeProvider);
                            }
                        }
                    }
                    finally
                    {
                        if (impersonationContext != null)
                        {
                            impersonationContext.Dispose();
                        }
                    }
                }
                catch
                {
                    throw; //Prevent impersonation leak through Exception Filters.
                }
                finally
                {
                    if (workflowDefinitionStream != null)
                    {
                        workflowDefinitionStream.Close();
                    }
 
                    if (ruleDefinitionStream != null)
                    {
                        ruleDefinitionStream.Close();
                    }
                }
            }
 
            if (workflowDefinitionContext == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CannotResolveConstructorStringToWorkflowType, constructorString)));
            }
 
            WorkflowServiceHost serviceHost = new WorkflowServiceHost(workflowDefinitionContext, baseAddresses);
 
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.WorkflowServiceHostCreated, SR.GetString(SR.TraceCodeWorkflowServiceHostCreated), this);
            }
            return serviceHost;
        }
 
        Type GetTypeFromString(string typeString, Uri[] baseAddresses)
        {
            if (baseAddresses == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("baseAddresses");
            }
            if (baseAddresses.Length == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.BaseAddressesNotProvided)));
            }
 
            Type workflowType = Type.GetType(typeString, false);
 
            if (workflowType == null)
            {
                this.typeProvider = new TypeProvider(null);
 
                // retrieve the reference assembly names from the compiled string supplied by the build manager
                string compiledString;
                try
                {
                    IDisposable impersonationContext = null;
                    try
                    {
                        try
                        {
 
                        }
                        finally
                        {
                            //Ensure Impersonation + Assignment is atomic w.r.t to potential Thread.Abort.
                            impersonationContext = HostingEnvironment.Impersonate();
                        }
                        compiledString = BuildManager.GetCompiledCustomString(baseAddresses[0].AbsolutePath);
                    }
                    finally
                    {
                        if (impersonationContext != null)
                        {
                            impersonationContext.Dispose();
                        }
                    }
                }
                catch
                {
                    throw; //Prevent impersonation leak through exception filters.
                }
 
                if (string.IsNullOrEmpty(compiledString))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.InvalidCompiledString, baseAddresses[0].AbsolutePath)));
                }
                string[] components = compiledString.Split('|');
                if (components.Length < 3)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.InvalidCompiledString, baseAddresses[0].AbsolutePath)));
                }
 
                //Walk reverse direction to increase our chance to match assembly;
                for (int i = (components.Length - 1); i > 2; i--)
                {
                    Assembly assembly = Assembly.Load(components[i]);
                    this.typeProvider.AddAssembly(assembly);
                    workflowType = assembly.GetType(typeString, false);
                    if (workflowType != null)
                    {
                        break;
                    }
                }
 
                if (workflowType == null)
                {
                    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                    {
                        this.typeProvider.AddAssembly(assembly);
 
                        workflowType = assembly.GetType(typeString, false);
                        if (workflowType != null)
                        {
                            break;
                        }
                    }
                }
            }
            return workflowType;
        }
    }
}