Top Related Projects
A library for patching, replacing and decorating .NET and Mono methods during runtime
Cecil is a library to inspect, modify and create .NET programs and libraries.
.NET Core library for dynamically loading code
ILMerge is a static linker for .NET Assemblies.
Quick Overview
Costura is a Fody add-in that embeds dependencies as resources in your .NET assembly. It eliminates the need for external DLLs by merging them into the main executable, simplifying deployment and distribution of your application.
Pros
- Simplifies deployment by creating a single executable
- Reduces the risk of missing dependencies during installation
- Improves application startup time by eliminating file I/O for loading assemblies
- Protects intellectual property by making it harder to reverse engineer dependencies
Cons
- Increases the size of the main executable
- May complicate debugging and error reporting
- Not suitable for applications that require runtime assembly loading
- Can potentially conflict with other Fody add-ins or custom build processes
Code Examples
- Basic configuration in FodyWeavers.xml:
<Weavers>
<Costura/>
</Weavers>
- Excluding specific assemblies:
<Weavers>
<Costura ExcludeAssemblies='AssemblyToExclude|AnotherAssembly'>
<ExcludeAssemblies>
YetAnotherAssembly
</ExcludeAssemblies>
</Costura>
</Weavers>
- Including unmanaged libraries:
<Weavers>
<Costura IncludeAssemblies='MyNativeLibrary'>
<Unmanaged32Assemblies>
MyNativeLibrary
</Unmanaged32Assemblies>
</Costura>
</Weavers>
Getting Started
-
Install the Fody NuGet package:
Install-Package Fody
-
Install the Costura.Fody NuGet package:
Install-Package Costura.Fody
-
Add the following to your FodyWeavers.xml file in the project root:
<Weavers> <Costura/> </Weavers>
-
Build your project. Costura will automatically embed dependencies as resources in your assembly.
Competitor Comparisons
A library for patching, replacing and decorating .NET and Mono methods during runtime
Pros of Harmony
- Offers runtime patching of .NET and Mono methods for modding
- Provides a powerful API for method manipulation and interception
- Supports a wide range of patching techniques, including prefix, postfix, and transpiler patches
Cons of Harmony
- Steeper learning curve due to its more complex API
- Potential for runtime errors if patches are not implemented correctly
- May have a slight performance overhead compared to compile-time solutions
Code Comparison
Harmony:
[HarmonyPatch(typeof(TargetClass), "TargetMethod")]
class Patch
{
static void Postfix(ref string __result)
{
__result = "Patched result";
}
}
Costura:
[assembly: Costura.AssemblyLoader(DisableCompression = true)]
Key Differences
- Harmony focuses on runtime method patching, while Costura is primarily used for embedding dependencies
- Harmony is more suitable for modding and extending existing applications, whereas Costura simplifies deployment by bundling dependencies
- Costura operates at compile-time, while Harmony applies patches at runtime
Use Cases
-
Choose Harmony for:
- Modding games or applications
- Intercepting and modifying method behavior at runtime
- Creating extensible plugin systems
-
Choose Costura for:
- Simplifying deployment by embedding dependencies
- Creating single-file executables
- Reducing the complexity of managing external libraries
Cecil is a library to inspect, modify and create .NET programs and libraries.
Pros of Cecil
- More versatile and low-level library for manipulating .NET assemblies
- Offers greater control and flexibility for advanced use cases
- Actively maintained with regular updates and improvements
Cons of Cecil
- Steeper learning curve due to its lower-level nature
- Requires more manual work to achieve similar results as Costura
- May be overkill for simple embedding scenarios
Code Comparison
Cecil (manipulating an assembly):
var assembly = AssemblyDefinition.ReadAssembly("MyAssembly.dll");
var type = assembly.MainModule.Types.First(t => t.Name == "MyClass");
var method = type.Methods.First(m => m.Name == "MyMethod");
method.Body.Instructions.Clear();
assembly.Write("ModifiedAssembly.dll");
Costura (embedding dependencies):
[assembly: Costura.AssemblyLoader(DisableCompression = true)]
Summary
Cecil is a powerful, low-level library for manipulating .NET assemblies, offering greater flexibility and control. It's suitable for advanced scenarios but has a steeper learning curve. Costura, on the other hand, focuses specifically on embedding dependencies into a single assembly, providing a simpler solution for this particular use case. The choice between the two depends on the specific requirements of your project and the level of control you need over assembly manipulation.
.NET Core library for dynamically loading code
Pros of DotNetCorePlugins
- Supports dynamic loading of assemblies at runtime in .NET Core applications
- Allows for true plugin architecture with isolated dependencies
- Provides a clean API for loading and unloading plugins
Cons of DotNetCorePlugins
- Requires more setup and configuration compared to Costura's simplicity
- May have a slight performance overhead due to runtime loading
- Limited to .NET Core applications, while Costura works with .NET Framework as well
Code Comparison
Costura (in FodyWeavers.xml):
<Weavers>
<Costura />
</Weavers>
DotNetCorePlugins:
var loader = PluginLoader.CreateFromAssemblyFile(
assemblyFile: "./plugins/MyPlugin.dll",
sharedTypes: new[] { typeof(IPlugin) },
isUnloadable: true);
var plugin = loader.LoadDefaultAssembly()
.CreateInstance("MyPlugin.PluginClass") as IPlugin;
DotNetCorePlugins offers more flexibility for runtime plugin management, while Costura provides a simpler solution for embedding dependencies. The choice between them depends on the specific requirements of your project, such as the need for dynamic loading or compatibility with different .NET versions.
ILMerge is a static linker for .NET Assemblies.
Pros of ILMerge
- More mature and established project with longer history
- Supports a wider range of .NET frameworks, including older versions
- Offers more fine-grained control over the merging process
Cons of ILMerge
- Requires manual configuration and command-line usage
- May have compatibility issues with certain types of assemblies
- Less seamless integration with build processes compared to Costura
Code Comparison
Costura:
[assembly: Costura.Fody.IncludeAssemblies("Newtonsoft.Json")]
ILMerge:
ilmerge /out:MyApp.exe MyApp.exe Newtonsoft.Json.dll
Costura uses a simple attribute to include assemblies, while ILMerge requires command-line execution. Costura integrates more seamlessly with the build process, whereas ILMerge offers more control but requires manual configuration.
Both tools aim to combine multiple assemblies into a single executable, but they differ in their approach and ease of use. Costura is generally easier to set up and use, especially for simpler projects, while ILMerge provides more flexibility and control for complex scenarios.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Costura is an add-in for Fody
Embeds dependencies as resources.
See Milestones for release notes.
This is an add-in for Fody
It is expected that all developers using Fody become a Patron on OpenCollective. See Licensing/Patron FAQ for more information.
!!! READ THIS !!! Package is in maintenance mode !!! READ THIS !!!
In .NET Core 3 there are two new features:
With these features included in the dotnet tool set, the value proposition of Costura is greatly diminished.
Therefore we strongly recommend to try out the alternatives mentioned above.
Supported use cases
Costura will be kept in maintenance mode for the following use-cases because they are used by the maintainers:
- C# projects (we have no experience with VB.NET, nor have any intention supporting this)
- Library linking (e.g. embed dependencies in library projects)
- Exe linking (e.g. embed dependencies in exe projects)
- Windows platforms
- Any advanced scenario that you are not willing to contribute (money, PR, etc) after discussing with the core contributors first
Non-supported use cases
- VB.NET (see above)
- Windows Services
- Non-Windows platforms
Note that this list may be updated and will become more strict over time.
NuGet installation
Install the Costura.Fody NuGet package and update the Fody NuGet package:
PM> Install-Package Fody
PM> Install-Package Costura.Fody
The Install-Package Fody
is required since NuGet always defaults to the oldest, and most buggy, version of any dependency.
Add to FodyWeavers.xml
Add <Costura/>
to FodyWeavers.xml
<Weavers>
<Costura/>
</Weavers>
How it works
Merge assemblies as embedded resources
This approach uses a combination of two methods
- Jeffrey Richter's suggestion of using embedded resources as a method of merging assemblies
- Einar Egilsson's suggestion using cecil to create module initializers
Details
This Task performs the following changes
- Take all assemblies (and pdbs) that have been marked as "Copy Local" and embed them as resources in the target assembly.
- Injects the following code into the module initializer of the target assembly. This code will be called when the assembly is loaded into memory
eg
static <Module>()
{
ILTemplate.Attach();
}
- Injects the following class into the target assembly. This means if an assembly load fails it will be loaded from the embedded resources.
Configuration Options
All config options are accessed by modifying the Costura
node in FodyWeavers.xml.
Default FodyWeavers.xml:
<Weavers>
<Costura />
</Weavers>
CreateTemporaryAssemblies
This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
Defaults to false
<Costura CreateTemporaryAssemblies='true' />
IncludeDebugSymbols
Controls if .pdbs for reference assemblies are also embedded.
Defaults to true
<Costura IncludeDebugSymbols='false' />
IncludeRuntimeReferences
Controls whether the runtimes
folder, used by .NET Core, for the embedded dependencies will be embedded.
Defaults to true
<Costura IncludeRuntimeReferences='false' />
UseRuntimeReferencePaths
Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.
For example, the reference system.text.encoding.codepages\5.0.0\runtimes\win\lib\net461\System.Text.Encoding.CodePages.dll
will be embedded as costura.system.text.encoding.codepages.dll.compressed
when false
, so Costura will automatically load it.
It will be embedded as costura.runtimes.win.lib.net461.system.text.encoding.codepages.dll.compressed
when true
(given IncludeRuntimeReferences='true'
and IncludeRuntimeAssemblies='System.Text.Encoding.CodePages'
), requiring custom user code to load the embedded compressed assembly.
Defaults to false
when the weaved assembly targets .NET Framework, true
when the weaved assembly targets .NET Core
<Costura UseRuntimeReferencePaths='true' />
DisableCompression
Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
Defaults to false
<Costura DisableCompression='true' />
DisableCleanup
As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
Defaults to false
<Costura DisableCleanup='true' />
DisableEventSubscription
The attach method no longer subscribes to the AppDomain.AssemblyResolve
(.NET 4.x) and AssemblyLoadContext.Resolving
(.NET 6.0+) events.
Only use in advanced scenarios (e.g. plugins where only the host should resolve the assemblies).
Defaults to false
<Costura DisableEventSubscription='true' />
LoadAtModuleInit
Costura by default will load as part of the module initialization. This flag disables that behaviour. Make sure you call CosturaUtility.Initialize()
somewhere in your code.
Defaults to true
<Costura LoadAtModuleInit='false' />
IgnoreSatelliteAssemblies
Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
Be advised, that DLL project assembly names ending with '.resources' (resulting in *.resources.dll
will lead to errors when this flag set to false
.
Defaults to false
<Costura IgnoreSatelliteAssemblies='true' />
ExcludeAssemblies / ExcludeRuntimeAssemblies
A list of assembly names to exclude from the default action of "embed all Copy Local references".
Do not include .exe
or .dll
in the names.
Can not be defined with IncludeAssemblies
.
Can use wildcards for partial assembly name matching. For example System.*
will exclude all assemblies that start with System.
. Wildcards may only be used at the end of an entry so for example, System.*.Private.*
would not work.
Can take two forms.
As an element with items delimited by a newline.
<Costura>
<ExcludeAssemblies>
Foo
Bar
</ExcludeAssemblies>
</Costura>
Or as an attribute with items delimited by a pipe |
.
<Costura ExcludeAssemblies='Foo|Bar' />
IncludeAssemblies / IncludeRuntimeAssemblies
A list of assembly names to include from the default action of "embed all Copy Local references".
Do not include .exe
or .dll
in the names.
Can not be defined with ExcludeAssemblies
/ IncludeRuntimeAssemblies
.
Can use wildcards at the end of the name for partial matching.
Can take two forms.
As an element with items delimited by a newline.
<Costura>
<IncludeAssemblies>
Foo
Bar
</IncludeAssemblies>
</Costura>
Or as an attribute with items delimited by a pipe |
.
<Costura IncludeAssemblies='Foo|Bar' />
Unmanaged32Assemblies & Unmanaged64Assemblies & UnmanagedArm64Assemblies
Mixed-mode assemblies cannot be loaded the same way as managed assemblies.
Therefore, to help Costura identify which assemblies are mixed-mode, and in what environment to load them in you should include their names in one or both of these lists.
Do not include .exe
or .dll
in the names.
Can use wildcards at the end of the name for partial matching.
Can take two forms.
As an element with items delimited by a newline.
<Costura>
<UnmanagedWinX86Assemblies>
Foo32
Bar32
</UnmanagedWinX86Assemblies>
<UnmanagedWinX64Assemblies>
Foo64
Bar64
</UnmanagedWinX64Assemblies>
<UnmanagedWinArm64Assemblies>
FooArm64
BarArm64
</UnmanagedWinArm64Assemblies>
</Costura>
Or as a attribute with items delimited by a pipe |
.
<Costura
UnmanagedWinX86Assemblies='Foo32|Bar32'
UnmanagedWinX64Assemblies='Foo64|Bar64'
UnmanagedWinArm64Assemblies='FooArm64|BarArm64'/>
Native Libraries and PreloadOrder
Native libraries can be loaded by Costura automatically. To include a native library include it in your project as an Embedded Resource in a folder called costuraX86
, costuraX64
or costuraArm64
depending on the runtime platform of the library.
Optionally you can also specify the order that preloaded libraries are loaded. When using temporary assemblies from disk mixed mode assemblies are also preloaded.
To specify the order of preloaded assemblies add a PreloadOrder
element to the config.
<Costura>
<PreloadOrder>
Foo
Bar
</PreloadOrder>
</Costura>
Or as a attribute with items delimited by a pipe |
.
<Costura PreloadOrder='Foo|Bar' />
CosturaUtility
CosturaUtility
is a class that gives you access to initialize the Costura system manually in your own code. This is mainly for scenarios where the module initializer doesn't work, such as libraries and Mono.
To use, call CosturaUtility.Initialize()
somewhere in your code, as early as possible.
class Program
{
static Program()
{
CosturaUtility.Initialize();
}
static void Main(string[] args) { ... }
}
Unit Testing
Most unit test frameworks need the .dll
s files in order to discover and perform the unit tests. You may need to add Costura and a configuration like the below to your testing assembly.
<Weavers>
<Costura ExcludeAssemblies='TargetExe|TargetExeTest'
CreateTemporaryAssemblies='true'
DisableCleanup='true'/>
</Weavers>
Icon
Merge from The Noun Project
Top Related Projects
A library for patching, replacing and decorating .NET and Mono methods during runtime
Cecil is a library to inspect, modify and create .NET programs and libraries.
.NET Core library for dynamically loading code
ILMerge is a static linker for .NET Assemblies.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot