Isolator.Fody
1.2.0
dotnet add package Isolator.Fody --version 1.2.0
NuGet\Install-Package Isolator.Fody -Version 1.2.0
<PackageReference Include="Isolator.Fody" Version="1.2.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Isolator.Fody" Version="1.2.0" />
<PackageReference Include="Isolator.Fody"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Isolator.Fody --version 1.2.0
#r "nuget: Isolator.Fody, 1.2.0"
#:package Isolator.Fody@1.2.0
#addin nuget:?package=Isolator.Fody&version=1.2.0
#tool nuget:?package=Isolator.Fody&version=1.2.0
Isolator.Fody
This is an add-in for Fody
This is a Fody add-in that isolate classes marked with the [Isolator] attribute by injection custom code to force the methods and constructor to run in a separate AssemblyLoadContext.
How to use
Inside your project file, add the following lines to reference the Isolator.Fody package:
<ItemGroup>
<PackageReference Include="Isolator.Fody" Version="*" IncludeAssets="build; compile" PrivateAssets="all" />
</ItemGroup>
Then, add the following configuration to enable the weaver:
<PropertyGroup>
<WeaverConfiguration>
<Weavers>
<Isolator />
</Weavers>
</WeaverConfiguration>
</PropertyGroup>
Next, mark the classes you want to isolate with the [Isolator] attribute:
[Isolator]
public class MyIsolatedClass
{
public MyIsolatedClass()
{
Console.WriteLine("Constructor implementation");
}
public void MyMethod()
{
Console.WriteLine("Method implementation");
}
}
When you build your project, the weaver will modify the IL code of the marked classes to ensure that their methods and constructors run in a separate AssemblyLoadContext.
The class and methods are modified and the [CompilerGenerated] attribute is added.
[CompilerGenerated]
public class MyIsolatedClass
{
[CompilerGenerated]
public MyIsolatedClass()
{
if (AssemblyLoader.IsDefault())
{
object obj = AssemblyLoader.CreateInstance(this, new object[0]);
return;
}
_isolator_ctor();
}
[CompilerGenerated]
public void MyMethod()
{
if (AssemblyLoader.IsDefault())
{
object[] args = new object[0];
object obj = AssemblyLoader.InvokeMethod(this, "_isolator_1_MyMethod", args, BindingFlags.Instance | BindingFlags.NonPublic);
}
else
{
_isolator_1_MyMethod();
}
}
[CompilerGenerated]
private void _isolator_ctor()
{
Console.WriteLine("Constructor implementation");
}
[CompilerGenerated]
private void _isolator_1_MyMethod()
{
Console.WriteLine("Method implementation");
}
}
Every time a method or constructor of the isolated class is called, it checks if it is running in the default AssemblyLoadContext. If it is, it uses reflection to invoke the method or constructor in a separate context.
AssemblyLoader
The AssemblyLoader class is injected into the assembly to handle the loading of the isolated classes into separate AssemblyLoadContext instances.
Isolator.Template project contains the source code for the AssemblyLoader class in the ILTemplate.cs file.
Features
- Support attribute
[Isolator]to mark classes for isolation. - Support for isolating static classes and methods.
- Support clone method to isolate internally called methods. (Clone to a unique name start with
_isolate_) - Support multiple methods with ref/out parameters. (There are some limitations when multiple methods with the same name.)
- Support isolate classes into different
AssemblyLoadContextinstances. ([Isolator("ContextName")]) - Support find existent
AssemblyLoadContextand use to share a common context between differentAssembly. - Support xml configuration for advanced settings.
- Isolate all classes/interfaces by name. (
ClassNamesandInterfaceNames) - Support context name with
{name}and{guid}placeholders. (ContextName)
- Isolate all classes/interfaces by name. (
Configuration Options
All config options are accessed by modifying the Isolator node in FodyWeavers.xml.
Default FodyWeavers.xml:
<Weavers>
<Isolator />
</Weavers>
ContextName
The name of the AssemblyLoadContext to use for isolation. If a context with this name already exists, it will be used. Otherwise, a new context will be created with this name.
Defaults to an empty string, which creates a unique name with the assembly name and the assembly module guid separated with dot "{name}.{guid}".
<Isolator ContextName='MyContextName' />
This can be overridden on a per-class basis by specifying a context name in the [Isolator("ContextName")] attribute.
The {name} will be replaced with the assembly name and the {guid} will be replaced with the assembly module guid at runtime.
The [Isolator("{name}.{guid}")] is equivalent to the default context name in the current assembly.
ClassNames
A list of class names to isolate. If a class name matches an entry in this list, it will be isolated even if it is not marked with the [Isolator] attribute.
Can take two forms.
As an element with items delimited by a newline.
<Isolator>
<ClassNames>
App
AppDB
Command
</ClassNames>
</Isolator>
Or as an attribute with items delimited by a pipe |.
<Isolator ClassNames='App|AppDB|Command' />
InterfaceNames
A list of interface names to isolate. If a interface name matches an entry in this list, it will be isolated even if it is not marked with the [Isolator] attribute.
Can take two forms.
As an element with items delimited by a newline.
<Isolator>
<InterfaceNames>
IExternalApplication
IExternalDBApplication
IExternalCommand
</InterfaceNames>
</Isolator>
Or as an attribute with items delimited by a pipe |.
<Isolator InterfaceNames='IExternalApplication|IExternalDBApplication|IExternalCommand' />
Debug Configuration Options
These options are used for debugging purposes and can be enabled or disabled as needed.
EnableDebug
Indicates whether to enable debug logging for the isolator. When enabled, additional debug information will be logged in the Debug console.
Defaults to false
<Isolator EnableDebug='true' />
SkipIsolator
Disable the isolator process without the need to remove the weaver from the project. This is useful for debugging purposes when you want to temporarily disable the isolator without modifying the project configuration.
Defaults to false
<Isolator SkipIsolator='true' />
This force the [Isolator] to be removed, and the class is not isolated.
LoadAtModuleInit
Indicates whether to load the AssemblyLoadContext at module initialization. When enabled, the context will be created and attached when the module is initialized.
Defaults to true
<Isolator LoadAtModuleInit='false' />
EnableCloneMethods
Indicates whether to clone methods that are called internally within the isolated class to ensure they also run in the isolated context.
Defaults to true
<Isolator EnableCloneMethods='false' />
EnableWriteBackRefOutParameters
Indicates whether to write back the values of ref and out parameters to the original method after invoking the isolated method.
Defaults to true
<Isolator EnableWriteBackRefOutParameters='false' />
References
This project use Fody and some of the base implementation was inspired by the Costura.Fody.
License
This project is licensed under the MIT License.
Do you like this project? Please star this project on GitHub!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net40 is compatible. net403 was computed. net45 was computed. net451 was computed. net452 was computed. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.