Resolve a multiTenant Service outside asp.net core pipeline - asp.net-core

Our project is using multitenancy to resolve some Service, lets say MyService based on SaasKit.
We also have a background task, which shares some of it's dependencies with the asp.net core controllers.
In the background task, any object that depends on MyService will get a null reference.
I can implement workarounds to get instances of MyService, like using service locator pattern, but this approach fails to create classes that depend on MyService without breaking DI and IOC logic.
So the question is: How can I get the same services that I can get from HttpContext with multitenancy, but get them without an HttpCoontext?

Related

How to add Application Insights to ILogger<T> for Unity DI into WCF Service

I have the unfortunate task of updating a WCF project to .NET Framework 4.8 and replacing the existing log4net exception handling with Microsoft Logging and Application Insights.
My approach was to implement Dependency Injection to make instantiation easier and because I am already used to that design approach with .NET Core. As you may know, WCF services adds its own complexity since WCF is responsible for instantiating the services and lower level objects (like custom customUserNamePasswordValidatorType). I was able to handle most of this by implementing a WCF Service Factory and updating the svc markup with it.
I have added Application Insights to the project via the appropriate NuGet packages which updates the web.config with appropriate httpModules for general exception handling. I was even able to add a custom TelemetryInitializer in Application_Start to include a few custom properties in the message.
My problem is getting an instance of ILogger<T> with the attached Application Insights provider into the instantiated service.
At first, I was getting an exception because of the parameterless constructor of Logger<T>. This was fixed by updating my WcfServiceFactory to the following
container
...
.RegisterType<ILoggerFactory, LoggerFactory>(TypeLifetime.Singleton)
.RegisterType(typeof(ILogger<>), typeof(Logger<>), TypeLifetime.Singleton);
This allowed an instance of the logger to be passed into the constructor of each service. However, calls to log messages are never written to App Insights and an inspection of the logger shows zero providers.
My guess is that because a new instance of LoggerFactory is being created, the already existing instance used in the httpModules is ignored.
According to https://github.com/unitycontainer/microsoft-logging, I need to refactor what I am doing and actually create an instance of a LoggerFactory and manually add the desired providers. My issue is that I cannot figure out how to do that with Application Insights. Everywhere else I used it, I would just call the AddApplicationInsights() extension method but that does not seem to be an option here (at least not with Unity).
So I guess my issue boils down to the following questions
Can I get the WcfServiceFactory to use the existing App Insights logging? Maybe establish something in Global.asx?
How can I manually register App Insights as a provider in the WcfServiceFactory including the custom telemetry?
No need to use ILogger if the intention is just to log a custom error. You can log exception on AppInsights directly using the telemetry client, like this:
var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);
telemetryClient.TrackException(new Exception("Logged random exception message."));

Startup Class Replacement in Hosted BackgroundService Apps

Normally with ASP.NET Core projects, I have access to the IWebHostBuilder creation, upon which I can register services and build configuration, and then I can get into a Startup class where I can inject any of the services or configurations that were registered while building the host. I use this two-stage approach quite often, as I usually need some services available within Startup to finish registering everything else.
Now I'm working on a Generic Host headless app, adding a BackgroundService with AddHostedService<T>. There is no Startup class in this scenario, so it seems all my dependencies have to be registered while creating the HostBuilder. I'm not able to use my normal services because of the lack of the second registration step.
When using the Generic Host/non-HTTP/BackgroundService/AddHostedService approach, how can I get two stages of dependency registration as I do in Web projects?

Dependency injection with asp.net core for properties

In spring boot you have the ability to inject properties or environment variables into your code so that they are available upon start time. If they are not set then the application fails upon starting.
Is there anything similar in ASP.net core? Basically I want to inject properties/environment variables and they are not set then the app should fail at startup and notify this.
In ASP.NET Core DI system, you can only inject a dependency via the constructor but you can use another DI System like AutoFac, Ninject or Lamar to use Property injection.

How to save info in asp.net core startup to be available in app

I have a set of 7 .Net Framework WebApi-based services that all share some common design elements. One shared element is that each will include the service version in the data that it returns from any of its endpoints. In each service, I determine the version from the executing assembly using reflection. I do this in Application_Start and store the result in a property that I create on the Global class that inherits from System.Web.HttpApplication. That way I do the reflection work once and access the result later from each of my methods.
I'm building a new service and this one is built on ASP.NET Core. So I'm trying to figure out how to do the same thing in ASP.NET Core. I can add the reflection logic in Startup.Configure (though it's not really about configuring the Http pipeline which is what Configure is supposed to be doing). Is there a better place than Startup.ConfigureServices or Startup.Configure, to put code that you want to run once on startup?
And where would I store the result to make it readily accessible to each of the downstream methods called from my controller actions?

WCF - StructureMap - Caching objects for the duration of the request only

So I already have a working implementation of StructureMap with the WCF service (including custom instance provider, behaviors, etc.)
When I try to have an object that is instantiated only once per user request, I use the InstanceScope.HttpContext and it throws because the context is null.
Do anyone have a proper way of doing that?
On the server-side of the WCF service? By default, WCF has nothing to do with ASP.NET and thus all your HttpContext etc. aren't there.
By default, your WCF services will be called on a "per-call" basis, e.g. each request gets a brand-new, separate, totally isolated instance of your service class. Why not just put those things into the service class as internal fields??
Or you might want to check out this blog post on how to abstract request state and providing sample implementations for ASP.NET (using HttpContext.Items) and WCF.