This is a simple solution built as a starter for writing Fody addins.
See also Fody usage.
Install the BasicFodyAddin.Fody NuGet package and update the Fody NuGet package:
PM> Install-Package BasicFodyAddin.Fody
PM> Update-Package Fody
The Update-Package Fody
is required since NuGet always defaults to the oldest, and most buggy, version of any dependency.
Add <BasicFodyAddin/>
to FodyWeavers.xml
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<BasicFodyAddin/>
</Weavers>
A project that contains all classes used for compile time metadata. Generally any usage and reference to this is removed at compile time so it is not needed as part of application deployment.
This project is also used to produce the Nuget package. To achieve this the project consumes two NuGets:
- Fody with
PrivateAssets="None"
. This results in produce NuGet package having a dependency on Fody with allinclude="All"
in the nuspec. Not that while this project consumes the Fody nuget, weaving is not performed on this project. This is dues to the FodyPackaging NuGet (see below) including<DisableFody>true</DisableFody>
in the msbuild pipeline. - FodyPackaging with
PrivateAssets="All"
. This results in the a NuGet being produced by this project, but no dependency on FodyPackaging in that produced NuGet.
The NuGet produced will be named after this project with the suffix .Fody
added.
This project should also contain all appropriate NuGet metadata properties. Many of these properties are defaulted by FodyPackaging but can be overriden.
The resultant NuGet will taget the same frameworks that this project targets.
The resultant NuGet will be created in a diretory named nugets
at the root of the solution.
The project that does the weaving.
The project has a NuGet dependency on FodyHelpers .
This project targets net46
and netstandard2.0
so that it can target msbuild.exe
and dotnet build
respectively.
It outputs a file named BasicFodyAddin.Fody
. The '.Fody' suffix is necessary for it to be picked up by Fody at compile time.
ModuleWeaver.cs is where the target assembly is modified. Fody will pick up this type during a its processing. Note that it must be named ModuleWeaver
ModuleWeaver
has a base class of BaseModuleWeaver
which exists in the FodyHelpers NuGet.
Called to perform the manipulation of the module. The current module can be accessed and manipulated via BaseModuleWeaver.ModuleDefinition
.
Called by fody when it is building up a type cache for lookups. This method should return all possible assemblies that the weaver may required for type resolution. In this case BasicFodyAddin requires System.Object
, so GetAssembliesForScanning
returns netstandard
and mscorlib
. It is safe to return assembly names that do not resolve for the runtime of current target assembly as these will be ignored.
To use this type cache a ModuleWeaver
can call BaseModuleWeaver.FindType
from within Execute
. For example in this project the following is called:
var objectRef = ModuleDefinition.ImportReference(FindType("System.Object"));
When BasicFodyAddin.dll
is referenced by a consuming project, it is only for the purposes configuring the weaving via attributes. As such is it nor required at runtime. With this in mind BaseModuleWeaver
has an opt in feature to remove the reference, meaning the target weaved application does not need BasicFodyAddin.dll
at run time. This feature can be opted in to via the following.
public override bool ShouldCleanReference => true;
BaseModuleWeaver
has a number of other members for logging and extensibility:
https://github.com/Fody/Fody/blob/master/FodyHelpers/BaseModuleWeaver.cs
In this case a new type is being injected into the target assembly that looks like this.
public class Hello
{
public string World()
{
return "Hello World";
}
}
See ModuleWeaver for more details.
A target assembly to process and then validate with unit tests.
Contains all tests for the weaver.
The project has a NuGet dependency on FodyHelpers .
It has a reference to the AssemblyToProcess
project, so that AssemblyToProcess.dll
is copied to the bin directory of the test project.
FodyHelpers contains a utility WeaverTestHelper for executing test runs on a target assembly using a ModuleWeaver.
A test can then be run as follows:
public class WeaverTests
{
static TestResult testResult;
static WeaverTests()
{
var weavingTask = new ModuleWeaver();
testResult = weavingTask.ExecuteTestRun("AssemblyToProcess.dll");
}
[Fact]
public void ValidateHelloWorldIsInjected()
{
var type = testResult.Assembly.GetType("TheNamespace.Hello");
var instance = (dynamic)Activator.CreateInstance(type);
Assert.Equal("Hello World", instance.World());
}
}
By default ExecuteTestRun
will perform a PeVerify on the resultant assembly
Lego designed by Timur Zima from The Noun Project