I understand C# Code Fragments and .NET Assemblies offer the same functionality for modular template development. We manage the code fragments in the CME and assembly code in Vi
The main differences between C# code Fragment and .net Assemblies in my point of view are categorized into below high level buckets.
Step-by-Step Debugging
With .net assemblies you could do step-by-step debugging from visual studio where as C# Code fragments it is not possible.
Re-Use or Base Classes
With .net assemblies you could extend ITemplate to create something like BaseTemplate and all your template could extend them so you have common design pattern, where as C# there is no concept of BaseTemplate other than Tridion ITemplate interface.
With .net assemblies you could add common utility classes (often TridionUtilities) and all your templates refer to the same TridionUtilities for common functionality. C# code fragment the utility functions need to be defined within the same TBB and cannot be reused with other TBBs unless you create a class and deploy to GAC.
Easier Upgrade Scans and Maintenance
With .net assemblies it is easier to do any upgrade scans like deprecated APIs/Methods simply referring to new dlls/.net framework. .net assemblies make it easy to identify potential impacts on planning either Tridion upgrades or .net framework upgrades. C# code fragments it is much harder to find the deprecated or any impacts of upgrade.
Developer Friendly
Obviously .net assemblies are developed using Visual Studio (developers love it!) vs. C# Code Fragments in a Text Editor (painful).
When I started back with Tridion 5.3, started with C# code fragments and quickly realized what a mistake I made for not going .net assemblies.
My vote is always .net assemblies and C# code fragments is not even in consideration unless I don't have a choice. lol..
I think the differences indeed are best explained by Frank's answer, as to how would you choose between the two. I normally say, since you are using Visual Studio anyways, always create a .NET Assembly TBB for your code. They offer you a lot more benefits like including 3rd party assemblies, allow for proper coding with classes and methods a lot easier and probably most important, allow for proper debugging (although this last one can be hard to setup depending on where you are, thinking of customer environments, firewalls etc.).
There are for me only two exceptions for using C# Fragments:
Number 2 is of course debatable, but you never can do without configuration properties, for a TBB most of these you can handle using a Parameters Schema, but sometimes it is just a lot easier, to directly write them in a C# Fragment and have that push them to the package for other TBBs to use.
In my training sessions, I usually referred to the following story of the only time I ever choose to use a C# Fragment TBB so far, indicating how much of an exception it is to use them:
I was working at a customer abroad, and my taxi for the airport was leaving in 10 minutes when one of the developers I was coaching asked me a question on how to get a list of items from a Folder in his TBB. I had already closed my Visual Studio and Outlook and was about to shutdown my laptop, but quickly browsed through some of my code samples to find what he needed. Knowing that starting up Visual Studio or Outlook would take a few minutes, I quickly pasted the code in a C# Fragment so he had it for easy reference.
A C# fragment is compiled into an assembly by Tridion when the template is first invoked and after it's been modified. To compile the fragment, Tridion wraps it in some "dungeon dressing" (bonus points for those who know where that term comes from) that:
Tridion.ContentManager
, Tridion.ContentManager.CommunicationManagement
, Tridion.ContentManager.ContentManagement
and Tridion.ContentManager.Templating
namespacesPackage
and Engine
available in fields called package
and engine
respectivelylog
using
for their namespaces yet)Edit: given the other answers it seems many people are not aware of how to accomplish certain tasks in C# fragment TBBs, so I'll document them below:
To import/use additional namespaces into your C# fragment, you need to use this syntax:
<%@ Import Namespace="Tridion.ContentManager.ContentManagement.Fields" %>
Note that this will only import namespaces from assemblies that are already referenced by Tridion. There is no mechanism for you to add references to other assemblies explicitly; so if you need a third-party DLL, you will need to add it to the GAC.
You can define custom fields and functions in your C# fragment by using this syntax:
<%!
public static string GetDate()
{
return new DateTime().ToString("u").Replace(" ", "T");
}
%>
The syntax for defining custom functions also allows you to define nested classes and/or member fields:
<%!
public class MyLittleHelper
{
public MyLittleHelper(string param1)
{
}
}
%>
I would never use C# fragments for the sole reason that it makes management of your code quite difficult and you need to manually deploy them. And if you do write your code from Visual Studio, then you should create a .NET Building Block assembly.
Frank has explained the difference between the two approaches, but that still leaves the question of how to choose between the two. My personal advise is to never use C# fragments for anything, with only one exception*. As you have found out, there is some dark magic going on in them that I personally do not like. Also, there is so much you cannot do in them that a .NET programmer is quite fond of, such as creating classes.
Putting my personal taste aside, I see only one reason why you would ever resort to C# fragments: if you do not have access to Visual Studio or another tool that builds DLLs. And that is not a very strong argument either: if you want a job done, you should get the proper tools!
*The exception being the C# fragments that Tridion automatically creates for each ITemplate in your assembly, of course.