Table of Contents

Referencing Only What You Need

AlliedBits.Tlumach ships the core library together with every platform integration assembly (Tlumach.WPF.dll, Tlumach.WinUI.dll, Tlumach.MAUI.dll, Tlumach.Avalonia.dll, Tlumach.UWP.dll, Tlumach.Extensions.Localization.dll) inside a single NuGet package. Depending on the target framework your project uses, you may notice that assemblies you never reference — for example Tlumach.MAUI.dll in an Avalonia-only application — end up copied into your build or publish output anyway.

Why this happens

Several platform integrations legitimately share the same target framework moniker (for example, WPF, WinUI, and MAUI-on-Windows all build for a net9.0-windows... framework). NuGet's package layout groups assemblies by target framework into a single lib\<TFM> folder, and when your project references the package via PackageReference, NuGet copies every assembly in the matched folder to your compile, runtime, and publish output — it has no way to know which of those assemblies your code actually uses. This is a limitation of how NuGet resolves package assets, not a bug in the referenced types themselves.

The fix: trim your project's output

Add the following to your application project's .csproj (the project that produces your .exe or app package — class library projects don't copy dependency assemblies to their own output by default, so this only matters for executable/publishable projects). Adjust the list of filenames to match the assemblies your project doesn't use, using the table below.

<Target Name="RemoveUnusedTlumachAssemblies"
        AfterTargets="ResolveAssemblyReferences">
  <ItemGroup>
    <ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)"
      Condition="'%(ReferenceCopyLocalPaths.Filename)' == 'Tlumach.WinUI'
              Or '%(ReferenceCopyLocalPaths.Filename)' == 'Tlumach.MAUI'
              Or '%(ReferenceCopyLocalPaths.Filename)' == 'Tlumach.UWP'
              Or '%(ReferenceCopyLocalPaths.Filename)' == 'Tlumach.Extensions.Localization'" />
  </ItemGroup>
</Target>

<Target Name="RemoveUnusedTlumachAssembliesFromPublish"
        AfterTargets="ComputeResolvedFilesToPublishList">
  <ItemGroup>
    <ResolvedFileToPublish Remove="@(ResolvedFileToPublish)"
      Condition="'%(ResolvedFileToPublish.Filename)' == 'Tlumach.WinUI'
              Or '%(ResolvedFileToPublish.Filename)' == 'Tlumach.MAUI'
              Or '%(ResolvedFileToPublish.Filename)' == 'Tlumach.UWP'
              Or '%(ResolvedFileToPublish.Filename)' == 'Tlumach.Extensions.Localization'" />
  </ItemGroup>
</Target>

The first target removes the unwanted assemblies from your regular build output (bin\<Configuration>\<TFM>\); the second removes them from dotnet publish output (including self-contained and single-file publishes, which MAUI and Avalonia apps commonly use). Both are needed — one does not imply the other.

The example above is written for an Avalonia-only application: it keeps Tlumach.Avalonia.dll and the core assemblies (Tlumach.dll, Tlumach.Base.dll, always required) while dropping WinUI, MAUI, UWP, and the Microsoft.Extensions.Localization adapter.

Which assemblies to keep, per application type

Your app Typical TargetFramework Keep Safe to exclude if unused
WPF net9.0-windows / net10.0-windows (or a -windows10.0.19041.0 variant) Tlumach.WPF Tlumach.WinUI, Tlumach.MAUI, Tlumach.UWP, Tlumach.Avalonia, Tlumach.Extensions.Localization*
WinUI net9.0-windows10.0.19041.0 / net10.0-windows10.0.19041.0 Tlumach.WinUI Tlumach.WPF, Tlumach.MAUI, Tlumach.Avalonia, Tlumach.Extensions.Localization*
MAUI net9.0-android21.0, net9.0-ios15.0, net9.0-maccatalyst15.0, net9.0-windows10.0.19041.0 (+ net10.0 equivalents) Tlumach.MAUI Tlumach.WPF / Tlumach.WinUI (Windows target only), Tlumach.Avalonia, Tlumach.Extensions.Localization*
UWP net9.0-windows10.0.26100.0 / net10.0-windows10.0.26100.0 Tlumach.UWP Tlumach.WPF, Tlumach.WinUI, Tlumach.MAUI, Tlumach.Avalonia, Tlumach.Extensions.Localization*
Avalonia net9.0 / net10.0 (or a Windows/mobile-specific TFM, if you target one) Tlumach.Avalonia Tlumach.Extensions.Localization* always; also Tlumach.WPF / Tlumach.WinUI / Tlumach.MAUI / Tlumach.UWP if you target a Windows or mobile TFM
Console / server / DI-only (no XAML framework) net9.0 / net10.0 / netstandard2.0 core only Tlumach.Avalonia (present even on plain net9.0/net10.0), Tlumach.Extensions.Localization*

* Keep Tlumach.Extensions.Localization if your app wires up Microsoft.Extensions.Localization's IStringLocalizer/DI integration — see Dependency Injection. Otherwise it can be excluded too.

Verifying the fix

After adding the target and rebuilding or republishing, check that only the assemblies you expect are present:

dir bin\Release\net9.0\Tlumach*.dll
dir bin\Release\net9.0\publish\Tlumach*.dll

You should see only Tlumach.dll, Tlumach.Base.dll, and the single platform assembly your project uses.

A note on this workaround

This is a project-file workaround for a NuGet packaging limitation — the assemblies you exclude are still part of the AlliedBits.Tlumach package and are still resolved at compile time, they are simply no longer copied to your build or publish output. If you maintain multiple application projects that need the same exclusions, consider moving the targets above into a shared Directory.Build.targets file instead of repeating them per project.