I'm interrupting my three-parter with a short post regarding something I learned just the other day. I was originally under the impression that in order to deploy a pipeline component, it must be placed in the Pipeline Components folder of the BizTalk installation directory. Apparently, this was the rule in BizTalk 2004, but it has since changed - pipeline components can now be GACed as well.
It's my understanding that the reason that the Pipeline Components directory exists is because developers need a standard place to put their components after they develop them so they can be easily added to the Visual Studio toolbar and subsequently used in new pipelines. It's also handy because you can easily deploy a debug version of a component there and step through the code in the debugger once the pipeline runs by attaching the VS debugger to the BTSNTSvc service corresponding to the host instance running the pipeline.
As Stephen Thomas points out here, make sure you know and understand where the component is going during development, where it's going in deployment, and that those two strategies mesh. He points out a scenario he ran into in which he built a pipeline component and added it to a pipeline before strong-naming it and GACing it. When he tried to deploy, the operation failed because it couldn't find the pipeline component.
Showing posts with label Component. Show all posts
Showing posts with label Component. Show all posts
Thursday, August 2, 2007
Monday, July 23, 2007
Debugging pipeline components in Visual Studio
I am not a Jedi of the Visual Studio Debugger, so I thought this was pretty magical when I found out how to do it.
To step through the code of a custom pipeline component in real time in the Visual Studio debugger, simply do the following:
To step through the code of a custom pipeline component in real time in the Visual Studio debugger, simply do the following:
- Compile the component as Debug. Make sure you've got breakpoints appropriately set.
- Place both the DLL and the PDB file in the Pipeline Components folder (as with all pipeline components, you don't need to GAC anything).
- Configure a receive location/send port with a pipeline that uses the custom component.
- Open the component solution in Visual Studio, and in the Debug menu, select Attach to Process. Attach to the process that represents the host instance your port is running on (BizTalk services are named BTSNTSvc.exe. I don't know of any way to identify which one represents the host instance you want, if you have more than one running).
- Once attached, trigger the component by running a file through BizTalk.
Why is Load being called twice on my pipeline component?
If you write a custom pipeline component and follow its execution through the debugger, you may be surprised to find that sometimes (depending on the component's configuration), the Load method may be called twice. This is confusing behavior at first until you start looking at the values that are being pulled out of the PropertyBag that's handed in to Load.
If the design-time configuration of your pipeline (the configuration items you can set on the component within the pipeline from the Send Port/Receive Location configuration dialog) consists of only default or only non-default values, Load will only be called once. If you have more than one design-time property and some are set to default values while others have non-default values, Load will be called twice. Each call will have a distinct PropertyBag - the first will contain the default values, and the second will contain the non-default values.
Just to clarify, the "default value" is the one you provide in Visual Studio in the Properties pane when you place the component into a pipeline. When setting values at design-time, default values show up as normal text while non-default values will appear in bold.
Here's the part that can trip up your code if you don't plan for it: The PropertyBag that contains the default values contains nulls for all the non-default values, and vice versa. If your component contains more than one design-time property, make sure that it doesn't choke on nulls, as you are guaranteed to get some. A simple way to do this is to give the component object a Dictionary member or some similar type of object that can contain the design-time property values. In your Load method, include some logic that looks to see if a value already exists in that Dictionary if it finds a null.
Oh, and speaking of default values for pipeline components, you can reset all the values to defaults if you simply select a different pipeline for the Send Port/Receive Location, and then select the original pipeline again. This is the only way I know of resetting the values.
If the design-time configuration of your pipeline (the configuration items you can set on the component within the pipeline from the Send Port/Receive Location configuration dialog) consists of only default or only non-default values, Load will only be called once. If you have more than one design-time property and some are set to default values while others have non-default values, Load will be called twice. Each call will have a distinct PropertyBag - the first will contain the default values, and the second will contain the non-default values.
Just to clarify, the "default value" is the one you provide in Visual Studio in the Properties pane when you place the component into a pipeline. When setting values at design-time, default values show up as normal text while non-default values will appear in bold.
Here's the part that can trip up your code if you don't plan for it: The PropertyBag that contains the default values contains nulls for all the non-default values, and vice versa. If your component contains more than one design-time property, make sure that it doesn't choke on nulls, as you are guaranteed to get some. A simple way to do this is to give the component object a Dictionary member or some similar type of object that can contain the design-time property values. In your Load method, include some logic that looks to see if a value already exists in that Dictionary if it finds a null.
Oh, and speaking of default values for pipeline components, you can reset all the values to defaults if you simply select a different pipeline for the Send Port/Receive Location, and then select the original pipeline again. This is the only way I know of resetting the values.
Labels:
BizTalk,
Component,
Design-Time,
Load,
Pipeline,
PropertyBag
Subscribe to:
Posts (Atom)