profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/davidfowl/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
David Fowler davidfowl Microsoft Bellevue, WA http://davidfowl.com/ Partner Software Architect at Microsoft on the ASP.NET team, Creator of SignalR

davidfowl/AspNetCoreDiagnosticScenarios 3437

This repository has examples of broken patterns in ASP.NET Core applications

CoreWCF/CoreWCF 921

Main repository for the Core WCF project

Azure/azure-signalr 154

Azure SignalR Service SDK for .NET

DamianEdwards/aspnet5-workshop 109

ASP.NET 5 workshop

Azure/service-fabric-mesh-preview 88

Service Fabric Mesh is the Service Fabric's serverless offering to enable developers to deploy containerized applications without managing infrastructure. Service Fabric Mesh , aka project “SeaBreeze” is currently available in private preview. This repository will be used for tracking bugs/feature requests as GitHub issues and for maintaining the latest documentation.

DamianEdwards/NDCLondon2013 55

Demos from my talks at NDC London 2013

damieng/Linq.Translations 52

Declare properties on an object that can be translated by LINQ

davidfowl/AspNetCoreRecipes 52

Recipes for common ASP.NET Core patterns

aspnet/AspNetSessionState 38

ASP.NET Session State (not for ASP.NET Core)

PR opened dotnet/aspnetcore

Make sure route binding isn't case sensitive
  • For error handling cases, we were doing a case sensitive match against route parameters instead of a case insensitive one.
  • Added tests

Fixes https://github.com/dotnet/aspnetcore/issues/35087

+104 -2

0 comment

2 changed files

pr created time in 7 minutes

create barnchdotnet/aspnetcore

branch : davidfowl/case-sensitivity

created branch time in 8 minutes

Pull request review commentdotnet/runtime

Additional Diagnostics in Dependency Injection

 internal sealed class DependencyInjectionEventSource : EventSource     {         public static readonly DependencyInjectionEventSource Log = new DependencyInjectionEventSource(); -        // Event source doesn't support large payloads so we chunk formatted call site tree+        public static class Keywords+        {+            public const EventKeywords ServiceProviderInitialized = (EventKeywords)0x1;+        }++        // Event source doesn't support large payloads so we chunk large payloads like formatted call site tree and descriptors         private const int MaxChunkSize = 10 * 1024; +        private readonly List<ServiceProvider> _providers = new();

Hmm maybe we should use a weak reference, that is a good idea.

eerhardt

comment created time in 4 hours

PullRequestReviewEvent

pull request commentOrchardCMS/OrchardCore

Configure ApiExplorer at the tenant level.

I think the build is broken right now.

jtkech

comment created time in 6 hours

push eventdotnet/aspnetcore

David Fowler

commit sha e3b6407e4cd83d4e1eed98e509a847a39725515c

Remove GetCallingAssembly usage (#35063) * Remove GetCallingAssembly usage - Today the WebApplicationBuilder tries to guess what the application name should be based on the immediate caller of the API using Assembly.GetCallingAssembly. This is because several components use the application name as a way to find the application assembly in order to do other things; - User secrets uses it to find the location of the directory that holds configuration secrets. - MVC uses it as the assembly to start the search for controllers, pages, etc. - Identifty uses it to find application parts. This API is a bit fragile for internal refactoring (if the immediate caller is anything except for user code, then we will treat our own assembly as the calling assembly) and more importantly, it breaks in NativeAOT scenarios. Instead of the calling assembly, we now default to the entry assembly. - This will "break" in scenarios where the WebApplication is started in a library and the entry point is the host application (controllers will be scanned in potentially the wrong place by default or it will find the wrong controllers). - Now that we have the option that allows specifying the name of the application name via WebApplicationOptions, In the future, we're investigating ways that the compiler can inject the calling assembly via an attribute similar to [CallerMemberName] that would capture the calling assembly in a more reliable and AOT friendly way. - Added a test that asserts that the default application name is the entry assembly. - Updated the slnf file * PR feedback - Change the name of the overriding assembly since the entry assembly is the default.

view details

push time in 8 hours

delete branch dotnet/aspnetcore

delete branch : davidfowl/remove-calling-assembly

delete time in 8 hours

PR merged dotnet/aspnetcore

Reviewers
Remove GetCallingAssembly usage area-runtime feature-minimal-hosting
  • Today the WebApplicationBuilder tries to guess what the application name should be based on the immediate caller of the API using Assembly.GetCallingAssembly. This is because several components use the application name as a way to find the application assembly in order to do other things;
  • User secrets uses it to find the location of the directory that holds configuration secrets.
  • MVC uses it as the assembly to start the search for controllers, pages, etc.
  • Identifty uses it to find application parts. This API is a bit fragile for internal refactoring (if the immediate caller is anything except for user code, then we will treat our own assembly as the calling assembly) and more importantly, it breaks in NativeAOT scenarios. Instead of the calling assembly, we now default to the entry assembly.
  • This will "break" in scenarios where the WebApplication is started in a library and the entry point is the host application (controllers will be scanned in potentially the wrong place by default or it will find the wrong controllers).
  • Now that we have the option that allows specifying the name of the application name via WebApplicationOptions, In the future, we're investigating ways that the compiler can inject the calling assembly via an attribute similar to [CallerMemberName] that would capture the calling assembly in a more reliable and AOT friendly way.
  • Added a test that asserts that the default application name is the entry assembly.
  • Updated the slnf file

Fixes #34838

+45 -12

2 comments

4 changed files

davidfowl

pr closed time in 8 hours

issue closeddotnet/aspnetcore

Minimal host does not work with NativeAOT

Describe the bug

While this isn't yet a fully supported scenario it was possible to build simple ASP.NET Core applications before with NativeAOT. This should in theory still be possible since the WebApplicationBuilder is a thin layer over the existing APIs. That's broken now because we're using Assembly.GetCallingAssembly to get the default application name.

To Reproduce

<!-- We ❤ code! Point us to a minimalistic repro project hosted in a GitHub repo. For a repro project, create a new ASP.NET Core project using the template of your your choice, apply the minimum required code to result in the issue you're observing.

We will close this issue if:

  • the repro project you share with us is complex. We can't investigate custom projects, so don't point us to such, please.
  • if we will not be able to repro the behavior you're reporting --> csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

<ItemGroup>
    <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="6.0.0-*" />
</ItemGroup>

</Project>

Program.cs

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", context => context.Response.WriteAsync("Hello World!"));

app.Run();
  1. Run dotnet publish -r win-x64 (I was on windows)
  2. Run the resulting published exe.

Exceptions (if any)

WebApplication1\bin\Debug\net6.0\win-x64\publish\WebApplication1.exe
Unhandled Exception: System.PlatformNotSupportedException: Operation is not supported on this platform.
   at System.Reflection.Assembly.GetCallingAssembly() + 0x7a
   at Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder(String[]) + 0x1d
   at <Program>$.<Main>$(String[]) + 0x3e
   at WebApplication1!<BaseAddress>+0x1080f37
   at WebApplication1!<BaseAddress>+0x1080fc5

cc @MichalStrehovsky @jkotas @agocke

closed time in 8 hours

davidfowl

Pull request review commentdotnet/aspnetcore

Remove GetCallingAssembly usage

 public void WebApplicationBuilderApplicationNameDefaultsToEntryAssembly()         [Fact]         public void WebApplicationBuilderApplicationNameCanBeOverridden()         {-            var assemblyName = Assembly.GetEntryAssembly().GetName().Name;+            var assemblyName = typeof(WebApplicationTests).Assembly.GetName().Name;

The only reason it could be random is because we're not loading the assembly.

davidfowl

comment created time in 10 hours

PullRequestReviewEvent

push eventdotnet/aspnetcore

David Fowler

commit sha cd03084f33bc0547adf09cadef9284d29eefd86d

PR feedback - Change the name of the overriding assembly since the entry assembly is the default.

view details

push time in 11 hours

Pull request review commentdotnet/aspnetcore

Remove GetCallingAssembly usage

 internal WebApplicationBuilder(Assembly? callingAssembly, WebApplicationOptions                  // We need to override the application name since the call to Configure will set it to                 // be the calling assembly's name.-                webHostBuilder.UseSetting(WebHostDefaults.ApplicationKey, (callingAssembly ?? Assembly.GetEntryAssembly())?.GetName()?.Name ?? string.Empty);+                webHostBuilder.UseSetting(WebHostDefaults.ApplicationKey, (Assembly.GetEntryAssembly())?.GetName()?.Name ?? string.Empty);

Yes, this is just the default. The API I added (WebApplicationOptions) allows setting the name. Or you can set it via command line args https://github.com/dotnet/aspnetcore/blob/8b06da35ddbc17280f02c0f1dcfd5fac1a40ea72/src/DefaultBuilder/test/Microsoft.AspNetCore.Tests/WebApplicationTests.cs#L387.

PS: You just made me realize I should update this test to be a different assembly name, now that the entry assembly is the default!

davidfowl

comment created time in 11 hours

PullRequestReviewEvent

issue commentdotnet/aspnetcore

SignalR force close client connection

Not sure why you can't, I've read the issue. Why cant' you get the access token and pass it to signalr?

maxima120

comment created time in 11 hours

Pull request review commentdotnet/installer

[main] Update dependencies from dotnet/sdk

       <SourceBuild RepoName="linker" ManagedOnly="true" />       <RepoName>linker</RepoName>     </Dependency>-    <Dependency Name="Microsoft.Net.Compilers.Toolset" Version="4.0.0-4.21404.8" CoherentParentDependency="Microsoft.NET.Sdk">+    <Dependency Name="Microsoft.Net.Compilers.Toolset" Version="4.0.0-4.21404.3" CoherentParentDependency="Microsoft.NET.Sdk">

cc @mmitche

dotnet-maestro[bot]

comment created time in 12 hours

PullRequestReviewEvent

Pull request review commentdotnet/installer

[main] Update dependencies from dotnet/sdk

       <SourceBuild RepoName="linker" ManagedOnly="true" />       <RepoName>linker</RepoName>     </Dependency>-    <Dependency Name="Microsoft.Net.Compilers.Toolset" Version="4.0.0-4.21404.8" CoherentParentDependency="Microsoft.NET.Sdk">+    <Dependency Name="Microsoft.Net.Compilers.Toolset" Version="4.0.0-4.21404.3" CoherentParentDependency="Microsoft.NET.Sdk">

Do we know where it came from?

dotnet-maestro[bot]

comment created time in 19 hours

PullRequestReviewEvent

pull request commentdotnet/aspnetcore

Remove GetCallingAssembly usage

/azp run

davidfowl

comment created time in 19 hours

issue commentdotnet/runtime

Dependency Injection of Open Generics via factory

This one bug Doubtful... There are also ways to do this on .NET Core with other DI containers.

wvpm

comment created time in 19 hours

PR opened dotnet/aspnetcore

Reviewers
Remove GetCallingAssembly usage
  • Today the WebApplicationBuilder tries to guess what the application name should be based on the immediate caller of the API using Assembly.GetCallingAssembly. This is because several components use the application name as a way to find the application assembly in order to do other things;
  • User secrets uses it to find the location of the directory that holds configuration secrets.
  • MVC uses it as the assembly to start the search for controllers, pages, etc.
  • Identifty uses it to find application parts. This API is a bit fragile for internal refactoring (if the immediate caller is anything except for user code, then we will treat our own assembly as the calling assembly) and more importantly, it breaks in NativeAOT scenarios. Instead of the calling assembly, we now default to the entry assembly.
  • This will "break" in scenarios where the WebApplication is started in a library and the entry point is the host application (controllers will be scanned in potentially the wrong place by default or it will find the wrong controllers).
  • Now that we have the option that allows specifying the name of the application name via WebApplicationOptions, In the future, we're investigating ways that the compiler can inject the calling assembly via an attribute similar to [CallerMemberName] that would capture the calling assembly in a more reliable and AOT friendly way.
  • Added a test that asserts that the default application name is the entry assembly.
  • Updated the slnf file

Fixes #34838

+44 -11

0 comment

4 changed files

pr created time in 21 hours

create barnchdotnet/aspnetcore

branch : davidfowl/remove-calling-assembly

created branch time in 21 hours

issue closeddotnet/aspnetcore

Signalr : Allow controlling maximum buffer size on client .

This is the same request as issue 17797 , as more and more people adopt to .net core and signalr the requirement for ability to avoid back pressure on client becomes a need. can you please allow maximum buffer size on .NET client.

closed time in a day

vinaykapoor

issue commentdotnet/aspnetcore

Signalr : Allow controlling maximum buffer size on client .

Closing this in favor of the duped issue.

vinaykapoor

comment created time in a day

PullRequestReviewEvent

Pull request review commentdotnet/runtime

Additional Diagnostics in Dependency Injection

 public void ScopeDisposed(int serviceProviderHashCode, int scopedServicesResolve         }          [Event(6, Level = EventLevel.Error)]-        public void ServiceRealizationFailed(string? exceptionMessage)+        public void ServiceRealizationFailed(string? exceptionMessage, int serviceProviderHashCode)         {-            WriteEvent(6, exceptionMessage);+            WriteEvent(6, exceptionMessage, serviceProviderHashCode);+        }++        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",+            Justification = "Parameters to this method are primitive and are trimmer safe.")]+        [Event(7, Level = EventLevel.Verbose)]+        private void ServiceProviderBuilt(int serviceProviderHashCode, int singletonServices, int scopedServices, int transientServices)+        {+            WriteEvent(7, serviceProviderHashCode, singletonServices, scopedServices, transientServices);+        }++        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",+            Justification = "Parameters to this method are primitive and are trimmer safe.")]+        [Event(8, Level = EventLevel.Verbose)]+        private void ServiceProviderDescriptors(int serviceProviderHashCode, string descriptors, int chunkIndex, int chunkCount)+        {+            WriteEvent(8, serviceProviderHashCode, descriptors, chunkIndex, chunkCount);         }          [NonEvent]-        public void ServiceResolved(Type serviceType)+        public void ServiceResolved(ServiceProvider provider, Type serviceType)         {             if (IsEnabled(EventLevel.Verbose, EventKeywords.All))             {-                ServiceResolved(serviceType.ToString());+                ServiceResolved(serviceType.ToString(), provider.GetHashCode());             }         }          [NonEvent]-        public void CallSiteBuilt(Type serviceType, ServiceCallSite callSite)+        public void CallSiteBuilt(ServiceProvider provider, Type serviceType, ServiceCallSite callSite)         {             if (IsEnabled(EventLevel.Verbose, EventKeywords.All))             {                 string format = CallSiteJsonFormatter.Instance.Format(callSite);                 int chunkCount = format.Length / MaxChunkSize + (format.Length % MaxChunkSize > 0 ? 1 : 0); +                int providerHashCode = provider.GetHashCode();                 for (int i = 0; i < chunkCount; i++)                 {                     CallSiteBuilt(                         serviceType.ToString(),-                        format.Substring(i * MaxChunkSize, Math.Min(MaxChunkSize, format.Length - i * MaxChunkSize)), i, chunkCount);+                        format.Substring(i * MaxChunkSize, Math.Min(MaxChunkSize, format.Length - i * MaxChunkSize)), i, chunkCount,+                        providerHashCode);                 }             }         }          [NonEvent]-        public void DynamicMethodBuilt(Type serviceType, int methodSize)+        public void DynamicMethodBuilt(ServiceProvider provider, Type serviceType, int methodSize)         {             if (IsEnabled(EventLevel.Verbose, EventKeywords.All))             {-                DynamicMethodBuilt(serviceType.ToString(), methodSize);+                DynamicMethodBuilt(serviceType.ToString(), methodSize, provider.GetHashCode());             }         }          [NonEvent]-        public void ServiceRealizationFailed(Exception exception)+        public void ServiceRealizationFailed(Exception exception, int serviceProviderHashCode)         {             if (IsEnabled(EventLevel.Error, EventKeywords.All))             {-                ServiceRealizationFailed(exception.ToString());+                ServiceRealizationFailed(exception.ToString(), serviceProviderHashCode);             }         }++        [NonEvent]+        public void ServiceProviderBuilt(ServiceProvider provider)+        {+            if (IsEnabled(EventLevel.Verbose, EventKeywords.All))

I'd like to be able to have this fire OnEventCommand if I use a specific keyword so we can get access to this data even if the application is already built.

Here's what I did in Kestrel https://github.com/dotnet/aspnetcore/blob/545d4eece7fcc5a67b27f6ba96636d9f476741ae/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelEventSource.cs#L354. The idea here is to handle when the event source is enabled and then fire the event (if the given keyword is on). In the kestrel case it always fires the event today because it doesn't have that much data (maybe we should tweak this), but for DI, we'd need to capture all service providers built in the application and then replay them here (and probably drop them from being rooted from the event source on dispose).

eerhardt

comment created time in a day

issue commentdotnet/runtime

[Perf] Regressions in Microsoft.Extensions.DependencyInjection.GetServiceIEnumerable

@pakrym spot the bug https://github.com/dotnet/runtime/blob/7c8f5fbee22030e69ca69615a157597cc035e854/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs#L170

DrewScoggins

comment created time in a day

issue commentdotnet/runtime

Add Dns event counters

Is there any low hanging fruit here we could tackle for .NET 6?

stephentoub

comment created time in a day