The LoadActivity method get the workflowDefinition from DB and create a temp.xaml file. Create the file stream and writes the workflow definition into the stream. (I was getting 'File in use' error while loading xaml file from stream so I closed the stream and again open in read mode to load the .xaml file) ActivityXamlServices.Load method uses this stream to load and return Activity object
...
var stream = new FileStream(Path.Combine(tempPath, TempXamlFile), FileMode.Create);
byte[] bytes = Encoding.ASCII.GetBytes(workflowDefinition);
stream.Write(bytes, 0, Encoding.ASCII.GetByteCount(workflowDefinition));
stream.Flush();
stream.Close();
stream = File.OpenRead(Path.Combine(tempPath, TempXamlFile));
var service = ActivityXamlServices.Load(stream);
stream.Flush();
stream.Close();
return service as Activity;
Now, we've got the activity, so we use WorkflowServiceHost class and pass this activity with baseAddress thus creating the host and return to the IIS.
And that's all, We've done the job. In the same manner we can load Workflow service. The only difference is we need to pass workflowservice object in WorkflowServiceHost as mentioned above (commented code)
Here's the complete code...
public class TestWorkflowServiceHostFactory : WorkflowServiceHostFactory
{
private const string TempXamlFile = "temp.xaml";
private const string TempXamlService = "temp.xamlx";
public string XamlRoutePrefix { get; set; }
public TriboldWorkflowServiceHostFactory(string routePrefix)
{
XamlRoutePrefix = routePrefix;
}
public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
var type = GetObjectOrThrowNotFound(() => Type.GetType(constructorString));
var activity = GetObjectOrThrowNotFound(() => Activator.CreateInstance(type) as Activity);
Activity activity1 = LoadActivity(XamlRoutePrefix);
var host = new WorkflowServiceHost(activity1, baseAddresses);
//WorkflowService service = LoadWFService(XamlRoutePrefix);
//var host = new WorkflowServiceHost(service, baseAddresses);
host.Description.Behaviors.Add(new AspNetCompatibilityRequirementsAttribute() { RequirementsMode = AspNetCompatibilityRequirementsMode.Required });
host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
return host;
}
private Activity LoadActivity(string searchString)
{
var input = new Dictionary<string, object>();
input["@WorkflowName"] = searchString;
DataTable dt = MvcApplication.FetchData.Fetch(input, "GetWorkflowList");
string workflowDefinition = dt.Rows[0][1].ToString();
string tempPath = Path.GetTempPath();
//if file already exists then delete it
if (File.Exists(Path.Combine(tempPath, TempXamlFile)))
File.Delete(Path.Combine(tempPath, TempXamlFile));
var stream = new FileStream(Path.Combine(tempPath, TempXamlFile), FileMode.Create);
byte[] bytes = Encoding.ASCII.GetBytes(workflowDefinition);
stream.Write(bytes, 0, Encoding.ASCII.GetByteCount(workflowDefinition));
stream.Flush();
stream.Close();
stream = File.OpenRead(Path.Combine(tempPath, TempXamlFile));
var service = ActivityXamlServices.Load(stream);
stream.Flush();
stream.Close();
return service as Activity;
}
private WorkflowService LoadWFService(string searchString)
{
var input = new Dictionary<string, object>();
input["@WorkflowName"] = searchString;
DataTable dt = MvcApplication.FetchData.Fetch(input, "GetWorkflowList");
string workflowDefinition = dt.Rows[0][1].ToString();
string tempPath = Path.GetTempPath();
//if file already exists then delete it
if (File.Exists(Path.Combine(tempPath, TempXamlService)))
File.Delete(Path.Combine(tempPath, TempXamlService));
var stream = new FileStream(Path.Combine(tempPath, TempXamlService), FileMode.Create);
byte[] bytes = Encoding.ASCII.GetBytes(workflowDefinition);
stream.Write(bytes, 0, Encoding.ASCII.GetByteCount(workflowDefinition));
stream.Flush();
stream.Close();
stream = File.OpenRead(Path.Combine(tempPath, TempXamlService));
var service = XamlServices.Load(stream);
stream.Flush();
stream.Close();
return service as WorkflowService;
}