Skip to content

Latest commit

 

History

History
155 lines (118 loc) · 5.83 KB

README.md

File metadata and controls

155 lines (118 loc) · 5.83 KB

dotnet6-csharp10-minimal-api

Playing with minimal APIs


Hey, so this was a fun attempt at minimal APIs that got sidetracked into creating a small .exe. If you want to see some real work in creating a shrunken .exe check out my project TinyWordle!


To create: dotnet new webapp

Via David Fowler

And remebering that a single file executable has to contain all the .dll files required to run it

	<PublishSingleFile>true</PublishSingleFile>
	<RuntimeIdentifier>win-x64</RuntimeIdentifier>
	<SelfContained>true</SelfContained>
	<PublishReadyToRun>true</PublishReadyToRun>

Making a smaller .exe

Checking out what (Building a self-contained game in C# under 8 kilobytes)[https://medium.com/@MStrehovsky/building-a-self-contained-game-in-c-under-8-kilobytes-74c3cf60ea04] does.

Attempt 1

	<PublishSingleFile>true</PublishSingleFile>
	<RuntimeIdentifier>win-x64</RuntimeIdentifier>  
dotnet publish -r win-x64 -c Release
Resulting size: 83,923 KB

Attempt 2

dotnet publish -r win-x64 -c Release /p:PublishTrimmed=true
Resulting size: 36,057 KB

Attempt 3

Using experimental AOT, need to remove single file part

dotnet publish -r win-x64 -c Release
Resulting size: 21,933 KB

Attempt 4

Some probably unnecessary (since using AOT) trimming commands via Trimming in .NET 5

dotnet publish -r win-x64 -c Release -p:PublishTrimmed=True -p:TrimMode=Link
Resulting size: 21,933 KB

Attempt 5

Back to reading the AOT docs

  <PropertyGroup>
    <InvariantGlobalization>true</InvariantGlobalization>
  </PropertyGroup>
dotnet publish -r win-x64 -c Release -p:PublishTrimmed=True -p:TrimMode=Link
Resulting size: 21,718 KB

Attempt 6

	<PropertyGroup>
		<IlcGenerateCompleteTypeMetadata>true</IlcGenerateCompleteTypeMetadata>
	</PropertyGroup>
	<ItemGroup>
		<TrimmableAssembly Include="dotnet6-csharp10-minimal-api" />
	</ItemGroup>
Resulting size: 22,617 KB

Except, it doesn't run.

System.Reflection.MissingMetadataException: 'System.Text.Json.Serialization.Converters.IEnumerableOfTConverter<System.Linq.Enumerable.SelectRangeIterator<WeatherForecast>,WeatherForecast>' is missing metadata. For more information, please visit http://go.microsoft.com/fwlink/?LinkID=392859

Attempt 7

<IlcDisableReflection>true</IlcDisableReflection>

Immediately terminates, but it makes sense since I'm pretty sure some of the aspnet core uses it.

Unhandled Exception: EETypeRva:0x0067BDB0: Reflection_Disabled
   at Internal.Reflection.ReflectionExecutionDomainCallbacksImplementation.GetDelegateMethod(Delegate) + 0x33
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.Configure(Action`2) + 0x3e
   at Microsoft.AspNetCore.Builder.WebApplicationBuilder.<>c__DisplayClass6_0.<.ctor>b__1(IWebHostBuilder) + 0x33
   at Microsoft.Extensions.Hosting.GenericHostWebHostBuilderExtensions.ConfigureWebHost(IHostBuilder, Action`1, Action`1) + 0x92
   at Microsoft.AspNetCore.Builder.WebApplicationBuilder..ctor(WebApplicationOptions, Action`1) + 0x188
   at Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder(String[]) + 0x41
   at Program.<Main>$(String[]) + 0x21
   at dotnet6-csharp10-minimal-api!<BaseAddress>+0x4a436f

Resulting size: 10,553 KB

Attempt 8

Turns out, it's not been working for awhile due to

System.Reflection.MissingMetadataException: 'System.Text.Json.Serialization.Converters.IEnumerableOfTConverter<System.Linq.Enumerable.SelectRangeIterator<WeatherForecast>,WeatherForecast>' is missing metadata. For more information, please visit http://go.microsoft.com/fwlink/?LinkID=392859
         at System.Reflection.Runtime.General.TypeUnifier.WithVerifiedTypeHandle(RuntimeConstructedGenericTypeInfo, RuntimeTypeInfo[]) + 0x88
         at System.Text.Json.Serialization.Converters.IEnumerableConverterFactory.CreateConverter(Type, JsonSerializerOptions) + 0x656
         at System.Text.Json.Serialization.JsonConverterFactory.GetConverterInternal(Type, JsonSerializerOptions) + 0x15
         at System.Text.Json.JsonSerializerOptions.GetConverterFromType(Type) + 0x1c0
         at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey, Func`2) + 0x85
         at System.Text.Json.JsonSerializerOptions.GetConverterFromMember(Type, Type, MemberInfo) + 0x9a
         at System.Text.Json.Serialization.Metadata.JsonTypeInfo.GetConverter(Type, Type, MemberInfo, Type&, JsonSerializerOptions) + 0x57
         at System.Text.Json.JsonSerializerOptions.<InitializeForReflectionSerializer>g__CreateJsonTypeInfo|120_0(Type, JsonSerializerOptions) + 0x3a
         at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey, Func`2) + 0x85
         at System.Text.Json.JsonSerializer.GetTypeInfo(JsonSerializerOptions, Type) + 0x73
         at System.Text.Json.JsonSerializer.SerializeAsync[TValue](Stream, TValue, JsonSerializerOptions, CancellationToken) + 0x37
         at Microsoft.AspNetCore.Http.HttpResponseJsonExtensions.<WriteAsJsonAsyncSlow>d__3`1.MoveNext() + 0x47

but that link takes us to a page that sorts out a rd.xsl file

After a night on it, prob not worth starting to understand optimising outputs when it involves something as complex a the asp.net pipeline lol

Next time I'll use the AOT documentation properly.