by community-syndication | Jan 10, 2011 | BizTalk Community Blogs via Syndication
Overview
ELMAH is an open source project used to add error logging capabilities to an ASP.NET Web application. ELMAH essentially provides a means for logging and reporting unhandled exceptions in applications. I came across this very nifty tool while working with the MASS LEG team to create the Legislative Automated Workflow System (LAWS) application for […]
by community-syndication | Jan 10, 2011 | BizTalk Community Blogs via Syndication
Check out the latest updates to the FabrikamShipping SaaS sample application. This sample provides a great example on how the Access Control service helps solve real-life identity federation requirements.
You can find more details in Vittorio Bertocci’s blog post.
If you want to learn more on the Access Control service please visit our website or the MSDN developers website.
If you haven’t started checking out Windows Azure AppFabric already make sure to take advantage of our free trial offer. Click the link below and get started!
As always, feel free to leave us feedback on the comments section of this blog.
by community-syndication | Jan 10, 2011 | BizTalk Community Blogs via Syndication
Rather short post this time. First of all a happy new year to everyone. BizTalk Hotrod 11 is out and can be obtained here. Go read
Technorati: biztalk server 2010
by community-syndication | Jan 9, 2011 | BizTalk Community Blogs via Syndication
Writing great software is an immense joy in my life. I truly enjoy working with business users and other developers to craft software which can make a marked and immediate difference for a business, something that presents real value. There isn’t a lot of rocket science here, it goes to the fundamental desire of all humans to make a difference in our world.
Fortunately for those who are looking for ways to do so, our world is full of situations that need to be adjusted. One of them, with all due respect to those in our industry who cling to their cherished degrees from universities, is that you do not need a four year degree to craft great software. Now certainly we all know people who have been successful without a traditional education, in fact you’re reading the blog of one right now. And I will be the first to tell anyone leaving High School that a four year degree is your most certain path to success in software development. But for some, that ship has sailed.
For some, the reality of life is such that leaving work is beyond their reach because of the need to support themselves. One such person as this is Christopher Jackson, a good friend of mine that has exceptional analytic skills but who also finds himself functionally unemployed currently, having lost his last job to a downsize from the economy, he now acts as a substitute teacher in the Fort Worth Independent School District for the incredible sum of $73 dollars per day. Compare that to the average salary for an entry level developer, approximately $56K/year, and I believe you will agree that cultivating his interest into a marketable skill set should have an impact on his life. Chris has always had an interest in writing software, but it is hard to find time to go back to school while working.
As such, Chris and I have come to arrangement, one that is an experiment for me but which I firmly believe in. Effective today, January 9th 2011, Chris has begun an unpaid internship with my company TimRayburn.net LLC which puts on Dallas TechFest and other projects of mine. During the internship, he will be working with me to increase his basic skills in development, and learn how to craft software from the ground up. Initially, he will be working on assignments with little real-world application, but eventually he will be assisting me on actual projects that deliver real world value. As I’m sure some will be curious on how I have structured this plan, I will lay out at a high level what is involved:
- A commitment to dedicate time to the effort. Chris will be spending time with my at least three days a week for multiple hours.
- A commitment from his spouse to support him in this effort. Chris is newly married, and his spouse needs to be on board if he is to have the support he will need at home.
- A time boxed commitment, for us initially of six months. This will allow Chris to commit, while also knowing that it has an end point, and that if he chooses to continue than changes can occur at that time.
- A penalty for not meeting the commitment. The details of which will not be public, but which are notable enough to impact his life should he decide to walk away from the commitment.
- A reasonable third party arbiter, trusted by both myself and Chris who will be able to settle any disagreements around the penalty should that need arise. My wife Kate will be serving that role, which for Chris and I who have been friends for over 15 years is agreeable.
I do not know how this will go, but I am certain it will generate blog posts as I learn while I teach. Any suggestions?
Average Entry Level Developer Salaries in Arlington, TX
|
|
entry level developer
|
$56,000 |
|
|
by community-syndication | Jan 9, 2011 | BizTalk Community Blogs via Syndication
One common complaint about BizTalk Server is that it’s not particular lightweight (many moving parts) and isn’t easy for an expert .NET developer to pick up immediately. I suspect this is one reason why we’ve seen multiple other .NET service buses (e.g. nServiceBus) pop up as viable alternatives. So, when it was announced that WCF […]
by community-syndication | Jan 9, 2011 | BizTalk Community Blogs via Syndication
I hope you’ve all been well over the break and enjoying the ’thinking time’ – I’ve
been keeping one ear to the ground and just on the lookout for new bits. Here’s one.
The BizTalk team have been busily working hard over the break and produced another
issue of BizTalk at it’s best – BizTalk Hotrod.
http://biztalkhotrod.com/Documents/BizTalkHotrod11_Q4_2010.pdf
Specifically this issues talks about:
-
Async communication with BizTalk across WCF-Duplex messaging.
-
Calling SAP RFCs from BizTalk – all you need to know.
Guys – the biztalk hotrod mag set is some of the best technical biztalk discussions
around, grab the previous issues and add them to your internal networks. A must.
Enjoy and talk to you soon.
Mick.
by community-syndication | Jan 8, 2011 | BizTalk Community Blogs via Syndication
In my last post I showed you how the _XamlStaticHelper class uses different semantics when loading assemblies referenced by XAML files.
Today I’m going to show you a solution I’ve built into the Microsoft.Activities library that can help you apply standard CLR behavior when loading referenced assemblies.
Strict Assembly Resolution for Compiled Workflows
Step 1: Download and reference Microsoft.Activities.dll
Download the latest version
Step 2: Create a partial class definition for your compiled workflow
In my example project, I have a compiled workflow named WorkflowCompiled.xaml. I have added a partial class with the same name and .cs extension
Step 3: Create a ReferencedAssemblies static property in your partial class
Add the FullName of any assemblies that you are referencing from your XAML
/// <summary>
/// Gets the referenced assemblies.
/// </summary>
/// <remarks>
/// The XamlAppDef build task generates a list of referenced assemblies automatically in the (XamlName).g.cs file
/// You can find the list of assemblies and version that need to be referenced there.
/// This property returns a simple string list of the assemblies that will cause them to be loaded using the
/// standard Assembly.Load method
/// </remarks>
public static IList<string> ReferencedAssemblies
{
get
{
// Create a list of activities you want to reference here
var list = new List<string> {
"ActivityLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c18b97d2d48a43ab",
};
// Add the standard list of references
list.AddRange(StrictXamlHelper.StandardReferencedAssemblies);
return list;
}
}
Step 4: Create a Constructor in your partial class with a XamlAssemblyResolutionOption argument
The default constructor in your partial class will use the loose assembly loading behavior. You must supply an alternate constructor to get the strict behavior
/// <summary>
/// Initializes a new instance of the <see cref="WorkflowCompiled"/> class.
/// </summary>
/// <param name="assemblyResolutionOption">
/// The assembly Resolution Option.
/// </param>
public WorkflowCompiled(XamlAssemblyResolutionOption assemblyResolutionOption)
{
switch (assemblyResolutionOption)
{
case XamlAssemblyResolutionOption.Loose:
this.InitializeComponent();
break;
case XamlAssemblyResolutionOption.Strict:
StrictXamlHelper.InitializeComponent(this, this.FindResource(), ReferencedAssemblies);
break;
default:
throw new ArgumentOutOfRangeException("assemblyResolutionOption");
}
}
Step 5: Construct your workflow using the new constructor passing XamlAssemblyResolutionOption.Strict
WorkflowInvoker.Invoke(new WorkflowCompiled(XamlAssemblyResolutionOption.Strict));
Result
Your compiled workflow will now behave like any other CLR object and construct successfully if and only if it can resolve the specific version of all referenced assemblies. If it cannot locate the assembly file it will throw a FileNotFoundException and if it can locate the file but it is not the correct version or public key token it will throw a FileLoadException.
Strict Assembly Resolution for Loose XAML
Loose XAML is an activity loaded from a XAML file using ActivityXamlServices.Load(). Unless the XAML file has FullName references (which it does not by default) ActivityXamlServices.Load will load with a partial name. This means it could load any assembly it finds with a matching name without regard to the version or public key token.
There are two ways to fix this.
- You can use the <qualifiedAssembly>configuration element to specify the FullName of the assembly you want to use
- Use Microsoft.Activities.StrictXamlHelper.ActivityLoad()
Step 1: Download and reference Microsoft.Activities.dll
Download the latest version
Step 2: Create a list of referenced assemblies
public static IList<string> GetWorkflowLooseReferencedAssemblies()
{
// Create a list of activities you want to reference here
var list = new List<string> { "ActivityLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c18b97d2d48a43ab", };
// Add the standard list of references
list.AddRange(StrictXamlHelper.StandardReferencedAssemblies);
return list;
}
Step 3: Load the activity using StrictXamlHelper.ActivityLoad()
// This will ensure the correct assemblies are loaded prior to loading loose XAML
var activity = StrictXamlHelper.ActivityLoad(
"WorkflowLoose.xaml", GetWorkflowLooseReferencedAssemblies());
WorkflowInvoker.Invoke(activity);
Summary
Loading the correct version of a referenced assembly is vital. The default behavior of both compiled workflows and loading loose XAML may result in unexpected behavior due to loading a newer version of the referenced assembly.
I recommend that you use StrictXamlHelper to ensure that you load the expected version of referenced assemblies.
by community-syndication | Jan 7, 2011 | BizTalk Community Blogs via Syndication
A spike is a short project where you investigate how something works and report back to the team with your results.
For this spike I want to answer the following questions
- What happens when a V1 workflow loads a V2 activity?
- What happens when a V2 workflow cannot find a V2 activity but a V1 activity is available?
- What difference if any does it make if the activity is deployed in the GAC?
- What difference does it make if you use Compiled or Loose XAML
I will run through a number of scenarios with various options. For each scenario the format is Activity (version), Host (version), Deploy (option), XAML option (which one runs first)
Deployment options
| Application Base |
Deploy the activity assembly to the same directory as the workflow application |
| GAC |
Deploy the activity assembly in the GAC |
XAML options
| Compiled XAML |
A .XAML file that has a XamlAppDef build task in Visual Studio and is deployed in the assembly – this is the default setting for XAML |
| Loose XAML |
.XAML file that is deployed as a file and loaded by ActivityXamlServices.Load |
Project artifacts
| Host |
XamlAssemblyResolution.exe |
Workflow Console Application with WorkflowCompiled.xaml and WorkflowLoose.xaml |
| Activity |
AcvitityLibrary1.dll |
Contains a custom activity named GetTypeInfo |
Scenario 1: Activity V1, Host V1, Deploy Application Base, Compiled/Loose
Expected: Both Compiled and Loose should use V1
Scenario 2: Activity V1, Host V1, Deploy GAC (V1), Compiled/Loose
Expected: Both Compiled and Loose should use V1 from the GAC even though the Activity DLL is in the Application Base
Actual: The activity was loaded from the GAC. For more info see How the Runtime Locates Assemblies.
Scenario 3: Activity V2, Host V1, Deploy Application Base, Loose
Expected: Activity V1 from the GAC will be used for both loose and compiled
Actual: Not Expected! When you run the Loose XAML first, it will load V2 from the file and the Compiled XAML will load V1.
Why does Loose XAML load a different activity version when run before compiled XAML?
Scenario 4: Activity V2, Host V1, Deploy Application Base, Compiled
Expected: Activity V1 from the GAC will be used for both loose and compiled
Actual: Behaves as expected
Scenario 5: Activity V2, Host V1, Deploy GAC (V1/V2), Loose
Expected: Activity V1 from the GAC will be used for both loose and compiled because the host was built for V1
Actual: Not Expected! When you run the Loose XAML first, it will load V2 from the GAC and the Compiled XAML will load V1.
Why does Loose XAML load a different activity version when run before compiled XAML?
Scenario 6: Activity V2, Host V1, Deploy GAC (V1/V2), Compiled
Expected: Activity V1 from the GAC will be used for both loose and compiled because the host was built for V1
Actual: Behaves as expected
Scenario 7: Activity V2, Host V1, Deploy GAC (V2), Loose/Compiled
Expected: Compiled and Loose will fail because V1 is not available
Actual: Not Expected! Both Compiled and Loose loaded V2 from the GAC even though they were not built for V2 of the activity
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?
Scenario 8: Activity V2, Host V1, Deploy Application Base, Loose/Compiled
Expected: Compiled and Loose will fail because V1 is not available
Actual: Not Expected! Both Compiled and Loose loaded V2 from the application base
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?
Scenario 9: Activity V1, Host V2, Deploy Application Base, Loose/Compiled
Expected: Compiled and Loose will fail because V2 is not available
Actual: Not Expected! Both Compiled and Loose loaded V1 from the application base
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?
Scenario 10: Activity V1, Host V2, Deploy GAC (V1), Loose/Compiled
Expected: Compiled and Loose will fail because V2 is not available
Actual: Not Expected! Both Compiled and Loose loaded V1 from the GAC
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?
Scenario 11: Activity V1/V2, Host V2, Deploy GAC (V2), Application Base (V1), Compiled
Expected: Workflow will run V2 from GAC
Actual: Compiled and Loose loaded V2 from the GAC as expected when Compiled ran first
Scenario 12: Activity V1/V2, Host V2, Deploy GAC (V2), Application Base (V1), Loose
Expected: Workflow will run V2 from GAC
Actual: Not Expected! Loose loaded V1 from Application Base and Compiled loaded V2 from the GAC
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?
Investigations
A: Because the generated class _XamlStaticHelper specifically tried to load the version that was referenced at compile time.
When you look at the activity assembly reference in XAML you will see that it does not include the version or public key token
xmlns:a="clr-namespace:ActivityLibrary1;assembly=ActivityLibrary1"
How does the version get referenced in compiled XAML?
The XamlAppDef build task will generate a file that creates a class which represents the compiled workflow. My workflow is WorkflowCompiled.xaml so the generated file (located under obj\x86) is WorkflowCompiled.g.cs. Contained in that file is a line of code that reveals where the XAML comes from
System.IO.Stream initializeXaml = typeof(WorkflowCompiled).Assembly.GetManifestResourceStream(resourceName);
When this class reads the XAML it uses a XamlSchemaContext to help it interpret the XAML and it gets the context from a generated class called _XamlStaticHelper. Here is the line of code.
System.Xaml.XamlSchemaContext schemaContext = XamlStaticHelperNamespace._XamlStaticHelper.SchemaContext;
So what? Well if we open the host assembly with Reflector and look at the _XamlStaticHelper.SchemaContext property we can see what is going on
if (AssemblyList.Count > 0)
{
target = new XamlSchemaContext(AssemblyList);
}
There is an AssemblyList property! And what does it contain? We see from the LoadAssemblies method that the XamlAppDef build task has generated a fully qualified reference to ActivityLibrary1 (version 1)
private static IList LoadAssemblies()
{
IList list = new List();
list.Add(Load("ActivityLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c18b97d2d48a43ab"));
// (a bunch of other assemblies here)
list.Add(Assembly.GetExecutingAssembly());
return list;
}
Because this code is generated at build time, the Compiled XAML will first try to load the specific version of the activity it was created with.
In spite of the fact that the compiled host assembly specifies a version of the activity library should be loaded; our testing shows that a compiled will load older or newer versions of the activity if the specific version is not available, and loose XAML will load any assembly with a matching name (even one that does not have a strong name).
The _XamlStaticHelper.Load() method is the reason why this happens
private static Assembly Load(string assemblyNameVal)
{
AssemblyName name = new AssemblyName(assemblyNameVal);
byte[] publicKeyToken = name.GetPublicKeyToken();
try
{
return Assembly.Load(name.FullName);
}
catch (Exception)
{
AssemblyName assemblyRef = new AssemblyName(name.Name);
if (publicKeyToken != null)
{
assemblyRef.SetPublicKeyToken(publicKeyToken);
}
return Assembly.Load(assemblyRef);
}
}
It first tries to load the assembly using the full name and if that fails it catches the exception and tries to load it with the name and public key token but no version. This is different than the typical CLR behavior which requires a specific version match.
Summary
To wrap this up I have to say be careful. WF4 workflows do not follow the same rules for assembly versioning that you might expect.
- Compiled XAML will try to load the specified version if available. If not, they will do a version independent load but will respect the PublicKeyToken so they won’t load assemblies with the wrong signature
- Loose XAML will load any matching assembly based on name alone with no respect for version or public key token. If the AppDomain has previously loaded the type from some other mechanism (CLR or XAML) then the Loose XAML will always load the type previously loaded.
- If you have to use Loose XAML and you want to be sure that you are loading a type of a certain version and/or PublicKeyToken you could use some code with a CLR reference to those types to cause the types to load into the AppDomain prior to calling ActivityXamlServices.Load
by community-syndication | Jan 7, 2011 | BizTalk Community Blogs via Syndication
This article focuses on one aspect of the recommendations I made for a client, which saw its way into the final Design Recommendations document I left with them at the end: how the use or misuse of color affects user interfaces.
by community-syndication | Jan 7, 2011 | BizTalk Community Blogs via Syndication
As many may already know, Scrum is an approach to software development that, rather than being a full process or methodology, is a framework that utilizes the Agile scheme to develop software. Instead of providing a complete, detailed description of how everything is to be done in a project from the beginning, much is left […]