LINQ to XML - creating an XML file from data collection

by 14. October 2008 20:55

One of the final requirements for our MAMLConverter project is to output the processed html tags (which resides in a List<ElementEnt> collection) and generate a XML file from it. 

Our Data Layer (of type IHTMLData) has a SaveData() method which does the job nicely using LINQ to XML:

public bool SaveData(List<ElementEnt> dataList)

{

    // TODO: Use filename (xml extension) of file submitted to workflow

    string fileName = "temp.xml";

 

    var xml = new XElement("developerConceptualDocument",

            new XAttribute("snlmx", Resources.snlmx),

            new XAttribute("snlmx_xlink", Resources.snlmx_xlink),

        (from d in dataList

        where d.MAMLTag != null  && !d.IsIgnore  && !d.IsCloseTag

        select new XElement(d.MAMLTag, d.Content)));

 

    // Final cleanup.  LINQ XML complains if we attempt to use

    // xmlns as a tag so we'll resolve after it is done above.

    xml.ToString()

        .Replace("snlmx_xlink", "xmlns:xlink")

        .Replace("snlmx", "xmlns")

        .StrToFile(fileName);

 

    // TODO: Remove - FOR DEVELOPMENT PURPOSES

    Process.Start(fileName);

    return true;

}
The data structure it has to work with follows:

 

 

[TestMethod]

public void TestSaveProcessedListAsXML()

{

    BootStrapper bootStrap = new BootStrapper();

    string fileName = string.Format(mockFileName, CurrentDir);

 

    IHTMLData dll = bootStrap.UnityContainer.Resolve<IHTMLData>();

    if (dll.LoadData(fileName))

    {

        MAMLState state = bootStrap.UnityContainer.Resolve<MAMLState>();

        state.HtmlData = dll.GetHtmlData();

 

        using (MAMLWorkflowRuntime wfrt =

            new MAMLWorkflowRuntime(bootStrap.UnityContainer))

        {

            wfrt.Start(typeof(HtmlToMAML));

            Assert.IsTrue(dll.SaveData(wfrt.State.Data.HtmlData)); 

            Assert.AreEqual(22, wfrt.State.Data.HtmlData.Count); 

        }

    }

    else

        Assert.Fail(dll.Exception.Message);

 

    Assert.Fail("Keep Unit Test checked for development");

}

Note below that we only have a few tags currently defined (resource file and TagCommands) so we still have some work to do.  We'll also have to do some special post processing but for the most part have the core requirement's infrastructure in place.  I've been able to complete the input/output of data easily/efficiently because of LINQ to XML.

 BEFORE

AFTER
 

Unity - factory pattern and extensibility

by 13. October 2008 08:28

The Unity and Workflow infrastructure, created for the MAMLConverter application, provides an extensible framework.  For example, to add a new HTML tag (for conversion to MAML) a developer only has to update the Resource file, add the new Tag<newTag>Command.cs file, compile and deploy.   An excerpt from the TagH2Command.cs command follows:

namespace Workflow.Library.TagCommands

{

    /// <summary>

    /// H2 tag

    /// </summary>

    public class TagH2Command : TagCommandBase

    {

        /// <summary>

        /// Executes this instance.

        /// </summary>

        public override void Execute()

        {

            // TODO: support attributes

            MAMLTag = Resources.h2;

        }

    }

Unity simplifies matters, we don't have an actual Factory class however we do have a class used to register the ITagCommands that will be used by Unity to resolve the concrete class. 

As each html tag hits the ElementProcessorActivity (in a ReplicatorActivity) it request the MAMLTag from the service.

The service turns to Unity to resolve the ITagCommand for the specified htmlTag

/// <summary>

/// Gets the MAML tag.

/// </summary>

/// <param name="htmlTag">The HTML tag.</param>

/// <returns></returns>

public string GetMAMLTag(string htmlTag)

{

    // We'll use the unity container as a factory

    ITagCommand TagCommand;

 

    // Ensure we have a configured ITagCommand - workaround:

    // http://www.codeplex.com/unity/WorkItem/View.aspx?WorkItemId=1991

    try

    {

        TagCommand = UnityContainer.Resolve<ITagCommand>(htmlTag);

        TagCommand.Execute();

    }

    catch

    {

        return htmlTag;

    }

    return TagCommand.MAMLTag;

}

 

Workflow - separation of concerns

by 13. October 2008 02:02

I'm enjoying workflow emmensely, I particularly like that we're forced to code in a manner that has us focus on the concerns of the Activity's Use Case.

For example the TagProcessorActivity and ElementProcessorActivity represented below:

Each of the above activities (pointed to by arrows) have a CodeActivity, SetCurrentElementCode and HtmlTagCode respectively; these code activities have a sole purpose in life.   The HtmlTag's purpose is to update/set the MAMLTag property to the value returned by the ProcessorService (service is set in SequenceActivityBase via Unity container).

The TagProcessorActivity (executes first) has the sole responsibility of setting the current element; the ReplicatorActivity provides us a CurrentIndex to notify us of our position in the Replicator list.  The TagProcessorActivity uses a method on our DataState object (of type IMAMLState) to update our state object; an excerpt from the MAMLState class follows:

/// <summary>

/// Sets the current element.

/// </summary>

/// <param name="activity">The activity.</param>

/// <returns></returns>

public ElementEnt SetCurrentElement(Activity activity)

{

    if (activity == null || activity.Parent ==null)

        return null;

    if (!(activity.Parent.Parent != null

            && activity.Parent.Parent is ReplicatorActivity))

        return null;

 

    ReplicatorActivity grandParent =

        activity.Parent.Parent as ReplicatorActivity;

    ElementBeingProcessed = grandParent.CurrentIndex;

    CurrentElement = (ElementEnt)

        grandParent.InitialChildData[grandParent.CurrentIndex];

    return CurrentElement;

}

Note: the [Sequence]ActivityBase is responsible for setting up the Activity so that the state is available; an excerpt from the ActivityBase follows:

protected override void OnActivityExecutionContextLoad(IServiceProvider provider)

{

    IWFState<IMAMLState> State;

    base.OnActivityExecutionContextLoad(provider);

    State = provider

        .GetService(typeof(IWFState<IMAMLState>)) as IWFState<IMAMLState>;

    Logger = State.UnityContainer.Resolve<ILoggerFacade>();

    ProcessorService = State.UnityContainer.Resolve<ITagProcessorService>();

    DataState = State.Data;

 

    WireupActivity(this);

}

 

At each level of processing there is a clear, testable separation of concern.

 

Source code available at http://www.Codeplex.com/MAMLConverter


 

Workflow - Replicator activity event processing different

by 13. October 2008 01:24

The ReplicatorActivity does not respect the base class wireup events as it's Activity and SequenceActivity counterparts do.  This BLOG demonstrates how we can hook into the current activity's Status Change event. 

Note in the following Log activity that the LogMAMLConverterStarted events are firing where the  LogTagProcessorStarted events are not - these activities are both LoggerActivity and share the same baseclass.

Debug(None): !! ACTIVITY WIREUP LogMAMLConverterStarted
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(None): ==> LogMAMLConverterStarted STATUS CHANGE - Status: Executing  Result: None
Debug(None): ==> LogMAMLConverterStarted EXECUTING:
Debug(None): MAML Converter Workflow Started
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): No HTML Tag
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [html]
Debug(None): MAML Tag set by service [htmlMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [head]
Debug(None): MAML Tag set by service [headMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [Untitled 1]
Debug(None): Processing HTML Tag [title]
Debug(None): MAML Tag set by service [titleMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [title]
Debug(None): MAML Tag set by service [titleMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [head]
Debug(None): MAML Tag set by service [headMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [body]
Debug(None): MAML Tag set by service [bodyMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [Welcome to the MAMLConverter Guide. This reference will help you understand and use this utility]
Debug(None): Processing HTML Tag [p]
Debug(None): MAML Tag set by service [pMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [p]
Debug(None): MAML Tag set by service [pMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [What is MAMLConverter]
Debug(None): Processing HTML Tag [h2]
Debug(None): MAML Tag set by service [h2MAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [h2]
Debug(None): MAML Tag set by service [h2MAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [The MAMLConverter is a utility that will allow you to create your help documents with your favorite editor (this utility was created using Expression Web content) and convert them to MAML]
Debug(None): Processing HTML Tag [p]
Debug(None): MAML Tag set by service [pMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [p]
Debug(None): MAML Tag set by service [pMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [Example]
Debug(None): Processing HTML Tag [h2]
Debug(None): MAML Tag set by service [h2MAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [h2]
Debug(None): MAML Tag set by service [h2MAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [The following & HTML ]
Debug(None): Processing HTML Tag [p]
Debug(None): MAML Tag set by service [pMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [p]
Debug(None): MAML Tag set by service [pMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [Will be converted to ]
Debug(None): Processing HTML Tag [p]
Debug(None): MAML Tag set by service [pMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [p]
Debug(None): MAML Tag set by service [pMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [body]
Debug(None): MAML Tag set by service [bodyMAML]
Debug(None): !! ACTIVITY WIREUP LogTagProcessorStarted
Debug(None): !! ACTIVITY WIREUP LogCurrentContent
Debug(None): !! ACTIVITY WIREUP LogNoHtmlTag
Debug(None): !! ACTIVITY WIREUP LogHasHtmlTag
Debug(None): !! ACTIVITY WIREUP LogMAMLTag
Debug(None): !! ACTIVITY WIREUP elementProcessorActivity1
Debug(None): !! ACTIVITY WIREUP tagProcessorActivity
Debug(High): Tag processor started
Debug(None): Content being processed [<Empty Line>]
Debug(None): Processing HTML Tag [html]
Debug(None): MAML Tag set by service [htmlMAML]
The thread '<No Name>' (0x1420) has exited with code 0 (0x0).

See http://www.CodePlex.com/MAMLConverter for source

 

Tags: , ,

Unity - a Workflow Trojan Horse

by 11. October 2008 00:40

Workflow is very powerful but I felt crippled without the Unity Container that I've come to depend on heavily in any application, no matter how large or small.   Case in point a new utility I'm working on to convert HTML to MAML so that I can take advantage of Sandcastles Help File Builder's  ConceptualContent which consist of MAML formated help files (no HTML).  Workflow seems optimal for this purpose.  The first requirement is (was) to plug in a Unity Container.

Workflow does offer the ability to register services that can be accessed from within activities, all that is required is to set an ExternalDataExchange attribute on your interface:

[ExternalDataExchange]

public interface IWFState<T>

{

    T Data { get; set; }

    IUnityContainer UnityContainer { get; set; }

    ILoggerFacade Logger { get; set; }

    void WireupActivity(Activity activity);

}

Then you load the service

public IWFState<T> State

{

    get { return _state; }

    set

    {

        _state = value;

        OnStateSet();

    }

}
/// <summary>

/// Loads the local services.

/// </summary>

public virtual void LoadLocalServices()

{

    ExternalDataExchangeService localServices = 
         new ExternalDataExchangeService();

    AddService(localServices);

    localServices.AddService(State);

}

 

However, this requires a redundant registration process (since I've already registered services with Unity).   I decided to use Unity as a trojan horse; I'll load one service, my state object which contains my UnityContainer, and then use my existing services via a UnityContainer property.  Important note:  some activities, i.e., Replicator and While will have to serialize referenced objects; any interfaces that Unity has to resolve in these activities will have to have [Serializable] attributes;

This permits my Activity to look as follows (ActivityBase has a UnityContainer property that returns State.UnityContainer):

namespace MAMLConvert.Activities.Logger

{

    /// <summary>

    /// Debug Logger

    /// </summary>

    public partial class LoggerDebugActivity : ActivityBase

  {

    public LoggerDebugActivity()

    {

      InitializeComponent();

    }

        protected override ActivityExecutionStatus

            Execute(ActivityExecutionContext executionContext)

        {

            UnityContainer.Resolve<ILoggerFacade>().Log(

                "Logging via Unity in the Activity!",

                    Category.Debug, Priority.None);

 

            return base.Execute(executionContext);

        }

  }

}

/// <summary>

/// Tests the workflow base ensure args is set on empty constructor.

/// </summary>

[TestMethod]

public void TestMAMLWorkflowBaseStartsAssignedWorkflow()

{

    using (MAMLWorkflowRuntime wfrt = new MAMLWorkflowRuntime())

    {

        Assert.IsNotNull(wfrt.Container);

        Assert.IsTrue(wfrt.Args.Count > 0, 
               "Should contain at least a UnityContainer");

        Assert.AreEqual("Initialized", wfrt.State.Data.MockInfo);

        Assert.AreEqual(wfrt.State.Logger.GetType().FullName,

            MockContainer.Resolve<ILoggerFacade>().GetType().FullName);

 

        wfrt.Start(typeof(HtmlToMAML));

    }

}

 

The above unit test yields the following results: 

 

Debug(None): !! ACTIVITY WIREUP loggerDebug
Debug(None): !! ACTIVITY WIREUP loggerTrace
Debug(None): !! ACTIVITY WIREUP loggerMessageBox
Debug(None): !! ACTIVITY WIREUP loggerEmail
Debug(None): !! ACTIVITY WIREUP Logger
Debug(None): ==> Logger STATUS CHANGE - Status: Executing  Result: None
Debug(None): ==> Logger EXECUTING:
Debug(None): ==> loggerDebug STATUS CHANGE - Status: Executing  Result: None
Debug(None): ==> loggerDebug EXECUTING:
Debug(None): Logging via Unity in the Activity!
Debug(None): ==> loggerDebug STATUS CHANGE - Status: Closed  Result: Succeeded
Debug(None): ==> loggerDebug CLOSED:
Debug(None): ==> Logger STATUS CHANGE - Status: Closed  Result: Succeeded
Debug(None): ==> Logger CLOSED:

 

Source code available at http://www.CodePlex.com/MAMLConverter
 

Notice

Blog videos and references to CodePlex projects are no longer valid