1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 namespace System.Workflow.Runtime
5 {
6     using System.ComponentModel.Design;
7     using System.Reflection;
8     using System.Runtime;
9     using System.ServiceModel;
10     using System.Workflow.ComponentModel;
11     using System.Workflow.ComponentModel.Compiler;
12 
13     abstract class WorkflowDefinitionContext
14     {
15         WorkflowRuntime workflowRuntime;
16 
17         public abstract string ConfigurationName
18         {
19             get;
20         }
21 
22         public abstract string WorkflowName
23         {
24             get;
25         }
26 
27         internal protected WorkflowRuntime WorkflowRuntime
28         {
29             get
30             {
31                 Fx.Assert(this.workflowRuntime != null, "Attempt to call WorkflowRuntime before Register");
32                 return this.workflowRuntime;
33             }
34         }
35 
CreateWorkflow()36         public abstract WorkflowInstance CreateWorkflow();
CreateWorkflow(Guid instanceId)37         public abstract WorkflowInstance CreateWorkflow(Guid instanceId);
GetWorkflowDefinition()38         public abstract Activity GetWorkflowDefinition();
39 
Register(WorkflowRuntime workflowRuntime, bool validate)40         internal void Register(WorkflowRuntime workflowRuntime, bool validate)
41         {
42             if (workflowRuntime == null)
43             {
44                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("workflowRuntime");
45             }
46 
47             this.workflowRuntime = workflowRuntime;
48 
49             OnRegister();
50 
51             if (!this.workflowRuntime.IsStarted)
52             {
53                 this.workflowRuntime.StartRuntime();
54             }
55 
56             if (validate)
57             {
58                 ValidateDefinition();
59             }
60         }
61 
CreateTypeProvider(Activity rootActivity)62         protected static TypeProvider CreateTypeProvider(Activity rootActivity)
63         {
64             TypeProvider typeProvider = new TypeProvider(null);
65 
66             Type companionType = rootActivity.GetType();
67             typeProvider.SetLocalAssembly(companionType.Assembly);
68             typeProvider.AddAssembly(companionType.Assembly);
69 
70             foreach (AssemblyName assemblyName in companionType.Assembly.GetReferencedAssemblies())
71             {
72                 Assembly referencedAssembly = null;
73                 try
74                 {
75                     referencedAssembly = Assembly.Load(assemblyName);
76                     if (referencedAssembly != null)
77                     {
78                         typeProvider.AddAssembly(referencedAssembly);
79                     }
80                 }
81                 catch (Exception e)
82                 {
83                     if (Fx.IsFatal(e))
84                     {
85                         throw;
86                     }
87                 }
88 
89                 if (referencedAssembly == null && assemblyName.CodeBase != null)
90                 {
91                     typeProvider.AddAssemblyReference(assemblyName.CodeBase);
92                 }
93             }
94 
95             return typeProvider;
96         }
OnRegister()97         protected abstract void OnRegister();
OnValidate(ValidationErrorCollection errors)98         protected abstract void OnValidate(ValidationErrorCollection errors);
99 
ValidateDefinition()100         void ValidateDefinition()
101         {
102             ValidationErrorCollection errors = new ValidationErrorCollection();
103             Activity rootActivity = GetWorkflowDefinition();
104 
105             ITypeProvider typeProvider = CreateTypeProvider(rootActivity);
106 
107             ServiceContainer serviceContainer = new ServiceContainer();
108             serviceContainer.AddService(typeof(ITypeProvider), typeProvider);
109 
110             ValidationManager validationManager = new ValidationManager(serviceContainer);
111             foreach (Validator validator in validationManager.GetValidators(rootActivity.GetType()))
112             {
113                 foreach (ValidationError error in validator.Validate(validationManager, rootActivity))
114                 {
115                     if (!error.UserData.Contains(typeof(Activity)))
116                     {
117                         error.UserData[typeof(Activity)] = rootActivity;
118                     }
119 
120                     errors.Add(error);
121                 }
122             }
123 
124             OnValidate(errors);
125 
126             if (errors.HasErrors)
127             {
128                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new WorkflowValidationFailedException(SR2.WorkflowValidationFailed, errors));
129             }
130         }
131 
132     }
133 }
134