Pages

Monday, March 14, 2011

Schema Design Pattern : REUSABLE STRUCTURES

So, lets create reusable structures. Open the editor by creating a new schema. When the schema appears in the Editor you get a Schema node and the Root Node. What we will do is to create our schema under the Root Node and then we add our global types at the same level as the Root Node.

So, lets create a global record, a global element and a global attribute - just to make sure we have all of our bases covered. Once these have been created then I will show you how we can use those within our schema.
Before we create these global items we need to keep in mind that you can create global types using records, elements or attributes. However, types created from elements can only be used in elements, records can only be used in records and attributes can only be used in attributes. This is especially important to keep in mind when importing a schema for reuse since you will need to know the types that are available for reuse since they will only be selectable for similar types.

First, lets create a global type. Create a record named Employee directly below the Schema node. Below the Employee record add three elements; EmployeeID, FirstName and LastName. Click on the Employee node and in the properties window, select the Data Structure Type and enter EmployeeType. This will be the name of the complex type that will be used when reusing this type.

Second, lets create a global element. Create an element named Company and place this directly below the Schema node as well. With elements and attributes you do not need to name it as you do with a Record (there is no Data Structure Type property on elements or attributes).

Third, lets create a global attribute. Create an attribute named EmployeeType directly below the Schema Node. Click the Derived By drop down in the properties window and select Restriction. This will expand the properties to include a Restriction Section. Set the Maximum Length to 1.

We have now created all of our reusable types, so now lets use them.

To begin with we will use our global element. Click on the Root node that was created with the Schema and add a Child Field Element. Click the Data Type drop down and in the list there will be an entry that says "Company (Reference)" - Select this value. We have now linked this element with the global element. Also, notice that the name of the element has changed to match the name of the global element.

Next, we will use our global records. Lets add two child records. The first will be named FTE and the second will be named Consultant. Lets start with the FTE record. Select the Data Structure Type drop down in the properties window and select EmployeeType (ComplexType). Repeat the same process for the Consultant Record. We now have two records re-using a the same global type.

Lastly, lets use the other global items that we created earlier to decorate the FTE record. The process is the same for attributes and elements. So on the FTE record add an attribute by right clicking on the FTE Record and selecting Child Field Attribute.

Once the attribute has been added, click the Data Type drop down in the properties window. At the bottom there will be an entry that says "EmployeeType(Reference)" - Select this value. We have now linked this attribute with the global attribute. Again, notice that the name of the attribute has changed to match the name of the global type. Here is a screen shot of what it looks like so far.
There is one last thing to look at while we are working on our attribute. You may have noticed that the properties for this attribute are read only. By changing the properties on the global definition we can affect the properties of the items that use these types. When we created the global attribute we selected Restriction and set the Maximum Length to 1. Change this value (or any other) and you will see the change flow through to be reflected in the attribute that points back to the global attribute.

What it really comes down to is that there are two different ways to select global types depending on what the type is. If the type is a record then select the globally defined type from the Data Structure Type property. If the type is a element or attribute then select the globally defined type from the Data Type property. Keep in mind that once the global type has been assigned then any changes to the globally defined type will appear in any of the locations in which the global type has been used.

So, now that you have seen the process all that you need to do is to follow any of the patterns described earlier in this series and create the schema you want..

There is one thing we still need to be aware of. If you are importing a schema in order to use global types defined in another schema file and there are promoted properties defined on any of the global types you will need to re-promote them in your schema for the promoted properties to take effect.

Monday, March 7, 2011

Working with Custom Pipeline Components in BizTalk

As you know, a change was made to how custom pipelines components behave in BizTalk Server. Now they can be placed in the Global Assembly Cache (GAC) as well as in the \Pipeline Components directly. So what does this mean? Put them in both place, one place, who knows?

In general, when working with custom pipeline components on a development system the components must be placed in the \Pipeline Components folder to be available for the designer. When working on a non-development server, putting the components only into the GAC can save on deployment time. Although this is not really the approach the help guide says (under Developing Custom Pipeline Components), this approach works great in most cases.
Today, I found a big GOT YOU with this approach if the custom component is not put into the GAC before it is used inside Visual Studios. I found that you must GAC the custom pipeline components BEFORE adding them to the Visual Studios Toolbox or you can run into runtime issues later on.
First, let us take a look at what happens when you add an unsigned and unGACed custom pipeline component to a project.
When you add the component to the Toolbox and drag it onto the Visual Studio design surface, a reference is added to the pipeline component. As seen below, when the component is not signed and not in the GAC a reference is added to the component in the \Pipeline Components folder.

Now, let us take a look at what happens when you add a signed and GACed custom pipeline to a project.

When you add the component to the Toolbox and use it in a pipeline, a reference is added to the pipeline component (same as before). But this time, the signed and GACed pipeline is referenced to the GACed version of the pipeline component.
So why does this matter? The problem I ran into was I added my custom pipeline component to my solution before I signed it and put it in the GAC. So when I went to deploy my solution to the development server with the pipeline component only in the GAC, I got a .net runtime error saying it could not find the pipeline in the \Pipeline Components folder.
Something else to point out is that the pipeline must be put into the GAC before you add the pipeline component to the Toolbox. Just being signed is not good enough.
The overall moral of the story is: If you only want to put your custom components into the GAC make sure you GAC it before you use it inside the designer.