This is the second article in a multi-part series about assemblies and how they relate to BizTalk. This part discusses deploying assemblies to BizTalk and where things need to go in order to work correctly.
The nature of BizTalk necessitates the existence of a special type of assembly, called a BizTalk assembly. A BizTalk assembly is a class library (.dll) assembly just like many other assemblies, but it has some special metadata in it that BizTalk uses for its own purposes. A BizTalk assembly is what's created when you build a BizTalk project in Visual Studio (as opposed to a standard C# class library project). If you've ever worked on a BizTalk project in VS, you'll know that unlike a standard class library or executable project, there are only a few types of resources you can add - schemas, pipelines, maps and orchestrations. These constructs are unique to BizTalk and are not fully understood or recognized by the rest of the .NET runtime or the GAC.
To deploy a BizTalk assembly, you must do two things: deploy it to the GAC, and register it within BizTalk. GACing an assembly is simple, and can be done with gacutil (discussed in pt. 1). Note that since a BizTalk assembly must be GACed to be used, it must be strongly-named. To strongly name a BizTalk assembly, first create a .snk (strong-name key) file using Visual Studio's sn.exe utility (the path is already present in a Visual Studio Tools command prompt; the path to it on my machine is C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sn.exe). The syntax is "sn.exe -k MyKeyFile.snk". Place the key in a location easily referenced from your project folder. In your BizTalk project in Visual Studio, open the project properties (right-click the project and select Properties). Click "Assembly" in the left pane, scroll down to "Assembly Key File", and enter the path to the .snk file or use the ellipsis button within the text field to browse to it. Click OK when finished - now the assembly that will result from building the project will be strongly-named.
Registering the assembly in BizTalk is required so BizTalk "knows" about it. An assembly is not registered directly from the GAC, it must be registered from a file on your machine. For this reason, you should treat your BizTalk assemblies like you treat program files for other applications - give them a folder somewhere where they aren't going to get moved or deleted. When you register a BizTalk assembly, BizTalk reads its metadata to discover what kinds of BizTalk artifacts (schemas, orchestrations, pipelines, maps) are present in it. Registration can be done via the command line, the admin console or Visual Studio. I will walk through the admin console and VS procedures - deploying from the command line is convenient for build/deploy scripts and the like, but if you're new to developing for BizTalk, odds are you'll be doing this manually from a GUI for a while.
To deploy a BizTalk assembly via the admin console, expand the application that you want to add the assembly to, right click the Resources folder and click "Add > BizTalk Assemblies..." Clicking the "Add" button in the next dialog will allow you to search for any file to add as a resource. Anything can be added as a resource to a BizTalk application, but what we are interested in right now is BizTalk assemblies, so dig up a .dll from a BizTalk VS project and add it. The File Type drop-down box should show System.BizTalk:BizTalkAssembly. Everything below this drop-down box is generally only relevant to the creation and usage of BizTalk MSI files, which I will cover in a later post. However, one of the checkbox options that will appear, "Add to the global assembly cache on add resource (gacutil)" will GAC the assembly for you once you click OK if you haven't GACed it yourself with gacutil.
To deploy a BizTalk assembly via Visual Studio, first configure the deployment options in the Deployment page of the project properties. Server and Configuration Database are required. Leaving Application blank will attempt to deploy to the default application, otherwise you may enter the name of a BizTalk application to deploy to. Redeploy should generally always be set to True, as should Install to Global Assembly Cache (this will GAC it for you). If you are working in a local development environment, go ahead and set Restart Host Instances to True as well - restarting the host instances is always a must when deploying or redeploying assemblies, it's just that you may want to wait for an opportune time to do it, and that may not be build/deploy time. Once you have filled out this page, selecting Deploy Solution or Deploy Project from the Build menu will attempt to deploy the assembly/assemblies to BizTalk for you, quick and easy.
If you are redeploying an assembly that already exists in BizTalk and the GAC, you generally need to follow the same procedure as when you deployed it the first time unless the version number has changed. Just like the GAC, multiple version numbers of the same assembly can co-exist within BizTalk. The components of those assemblies will exist as separate entities and are distinguished by the version number of the assembly in their full name. If the version number of your assembly has not changed, simply deploy it from Visual Studio with Redeploy set to True, or manually reGAC it and re-add it as a BizTalk Assembly resource from the admin console and make sure Overwrite is checked. Note that simply replacing the .dll on disk and in the GAC is not enough - it must be re-added to BizTalk's resources so it can read the assembly metadata again.
If the version number has changed as a part of development and you don't want the versions to co-exist (i.e. you want one definitive version in your environment to avoid confusion), you need to remove the old assembly by right-clicking it from the Resources screen of your application and clicking Remove. For this to succeed, none of the assembly's components can be used as configuration items within any of your binding objects (ports, orchestrations, etc.). The admin console will warn you and fail the operation if this is not true. Note that removing the resource from BizTalk does not unGAC the assembly: to keep your GAC clean, I suggest removing the assembly from it if you are no longer using it.
That wraps up part two of the deployment posts. In the third and last post I will discuss MSI files, binding files and assembly references, as well as pipeline components, which are the exceptions to all of the rules.
Showing posts with label assemblies. Show all posts
Showing posts with label assemblies. Show all posts
Wednesday, August 1, 2007
On BizTalk, Assemblies and Deployment, pt. 1
This is the first article in a multi-part series about assemblies and how they relate to BizTalk. This part covers what you need to know about assemblies in general in order to understand what they do and how to deploy them properly. I don't endeavor to cover every detail of .NET assemblies and how they are put together, but this hits most of the big topics. It's a bit long, so feel free to just skim.
The concept of assemblies and the GAC can be very confusing to a BizTalk developer who hasn't interacted with these ideas in .NET before. Fortunately, if you don't want to spend the time, there's no need to have a complete, detailed understanding of what assemblies are and how they work. By grasping a few simple ideas, working with assemblies in BizTalk becomes very easy, and gives you great insight into how BizTalk and .NET actually work with assemblies.
To get a good overall idea of what an assembly is, Wikipedia has a fairly descriptive and high-level article about it: http://en.wikipedia.org/wiki/.net_assembly.
Here's the short-short version: an assembly contains your compiled code, resources, and some metadata about that code and those resources. That's about it. Typically, a "project" in Visual Studio (which can consist of multiple code files, resources, references to other assemblies, etc.) equates to an assembly - a single .dll or .exe file. When you build that project it compiles your code and puts all of those other resources together in a big pile and stuffs it into a .dll or .exe. Additionally, it creates an "index" of machine-readable metadata that is incredibly useful - it contains all the information about what callable methods are in that code, it powers Visual Studio's IntelliSense functionality, and generally provides enough information to let everything outside of the assembly know what it does - just not how exactly it does it. Whenever you create any kind of application, all of the code and resources used to run it are in one or more .dll or .exe files. If you make a lot of little one-off "toolbelt" applications that are contained in a single Visual Studio project, that .exe that you get after you build has all of the code in it. If you were to spread the code over multiple projects and add the appropriate references within those projects, then when you ran the .exe and did something in your application that required code in one of those assemblies, the assembly it needs must be in the right place or the application will throw an exception. What is "the right place" for an assembly? I'll discuss that momentarily.
The next important bit about assemblies is how they are named. A name might seem trivial, but it contains a lot of information and is a guaranteed unique identifier for the assembly. The full name of an assembly has four parts: The short name, the version, the culture, and the public key token.
This is where I get to the part about where assemblies need to be placed so they can be used. The part of .NET that finds assemblies when it needs them is called Fusion. If you are running an application that has references to other assemblies and it needs one of those other assemblies, Fusion kicks in and looks for assemblies in the following places in this order (this is direct from the .NET Assembly article on Wikipedia):
That's it for the lecture on assemblies. Next post I'll talk about how assemblies and the GAC work with BizTalk - how to deploy and redeploy assemblies, what needs to be GACed and what doesn't, where to put things, etc.
The concept of assemblies and the GAC can be very confusing to a BizTalk developer who hasn't interacted with these ideas in .NET before. Fortunately, if you don't want to spend the time, there's no need to have a complete, detailed understanding of what assemblies are and how they work. By grasping a few simple ideas, working with assemblies in BizTalk becomes very easy, and gives you great insight into how BizTalk and .NET actually work with assemblies.
To get a good overall idea of what an assembly is, Wikipedia has a fairly descriptive and high-level article about it: http://en.wikipedia.org/wiki/.net_assembly.
Here's the short-short version: an assembly contains your compiled code, resources, and some metadata about that code and those resources. That's about it. Typically, a "project" in Visual Studio (which can consist of multiple code files, resources, references to other assemblies, etc.) equates to an assembly - a single .dll or .exe file. When you build that project it compiles your code and puts all of those other resources together in a big pile and stuffs it into a .dll or .exe. Additionally, it creates an "index" of machine-readable metadata that is incredibly useful - it contains all the information about what callable methods are in that code, it powers Visual Studio's IntelliSense functionality, and generally provides enough information to let everything outside of the assembly know what it does - just not how exactly it does it. Whenever you create any kind of application, all of the code and resources used to run it are in one or more .dll or .exe files. If you make a lot of little one-off "toolbelt" applications that are contained in a single Visual Studio project, that .exe that you get after you build has all of the code in it. If you were to spread the code over multiple projects and add the appropriate references within those projects, then when you ran the .exe and did something in your application that required code in one of those assemblies, the assembly it needs must be in the right place or the application will throw an exception. What is "the right place" for an assembly? I'll discuss that momentarily.
The next important bit about assemblies is how they are named. A name might seem trivial, but it contains a lot of information and is a guaranteed unique identifier for the assembly. The full name of an assembly has four parts: The short name, the version, the culture, and the public key token.
- The short name is typically the name of the assembly without the file extension, e.g. NW.Applications.MyAssembly. This short name is also typically used as the namespace of all of the modules in the assembly - a namespace is simply something that helps to uniquely identify a module. There's lots of code in the universe, and it's highly likely that for every module, there's another module out there with the same name - let's take a hypothetical module called NumberCruncher. The namespace is like a surname that gets tacked onto it, usually containing a company name or a product name, that guarantees that those two modules with the same name are still unique - NumberCruncher in the NW.Applications.MyAssembly namespace is different from the NumberCruncher module in the ABC.Software.EnterpriseApps namespace. For this reason, many assembly names are like my sample one above: multiple tokens separated with dots, each token representing some kind of arbitrary hierarchy that's unique to my company or organization.
- The version number of the assembly, presented like so: 1.0.4.0. The names for each of those values are "major version," "minor version", "build" and "revision." Major version is typically used to signify the product version: Is this SuperToolbox 2 or 3? Minor version represents things like service packs or patches. Build number is typically incremented by the developer every time the assembly is built - this number is often represented by four digits (filling in zeroes if necessary) because builds happen thousands of times. The last number can be used for things like hot fixes. Some developers may increment the last two numbers based on the date and time the build was completed at. Here's the important bit about versions: Two versions of the same assembly can co-exist within the GAC (keep reading), and are unique! Note that an assembly has an "assembly version" and a "file version." The one that really counts here is the assembly version. These two version numbers don't necessarily have to always be the same: one way to manage version numbers is to only increment the file version while you are developing. This helps avoid confusion with version numbers when you keep redeploying your code for testing - the assembly version always stays the same, but the file version (which does not make an assembly unique, but can still be viewed) can be used to determine exactly what build you are using.
- Culture provides information about the language that the assembly is presented in (human language, not programming language). This will typically be "neutral."
- Public key token: a 16-character hexadecimal string, the public half of a public-key cryptography pair. I won't discuss the details of how public-key cryptography works here, but the short and long of it is that only people who have the private half of the key can generate assemblies that have that public half of the key. This token essentially ensures that the assembly has come from a certain author and is guaranteed authentic. An assembly does not have to be given a public key token. If it has one, it can be called a "strongly-named assembly." Assigning a strong name is done in Visual Studio using a .snk file, which can be generated by using a Visual Studio command-line tool. An assembly must be strongly-named to be placed in the GAC.
This is where I get to the part about where assemblies need to be placed so they can be used. The part of .NET that finds assemblies when it needs them is called Fusion. If you are running an application that has references to other assemblies and it needs one of those other assemblies, Fusion kicks in and looks for assemblies in the following places in this order (this is direct from the .NET Assembly article on Wikipedia):
- If the assembly is strongly named it will first look in the GAC (your app knows if the assembly is strongly named because it captures this information from the assembly when you add a reference to it in your project).
- Fusion will then look for redirection information in the application's configuration file. If the library is strongly named then this can specify that another version should be loaded, or it can specify an absolute address of a folder on the local hard disk, or the URL of a file on a web server. If the library is not strongly named, then the configuration file can specify a subfolder beneath the application folder to be used in the search path.
- Fusion will then look for the assembly in the application folder with either the extension .exe or .dll.
- Fusion will look for a subfolder with the same name as the short name (PE file name) of the assembly and then looks for the assembly in that folder with either the extension .exe or .dll.
That's it for the lecture on assemblies. Next post I'll talk about how assemblies and the GAC work with BizTalk - how to deploy and redeploy assemblies, what needs to be GACed and what doesn't, where to put things, etc.
Subscribe to:
Posts (Atom)