How to get ConnectionString in a ClassLibrary? - asp.net-core

Connection strings exist in appsettings.json in an ASP.Net MVC Core Project. I also have a Class Library Project in the same solution and there I want to get the connection string of web project, I am unable to find help in official resources, how can I achieve this?
Update: The class library is of .Net 4.6.1, also in the ASP.Net Core Project I am targeting .Net 4.6.1.

Register Configuration in Startup.cs
public void ConfigureServices(IServicesCollection services)
{
services.AddSingleton(Configuration);
}
Then you can inject it in controller or any other library project class
public HomeController(IConfigurationRoot Configuration)
{
this.Configuration= Configuration;
}
Then you can get connection string as you get in Startup.cs
Configuration.GetConnectionString("DefaultConnection")

Related

How to access appSettings.json which belongs to a .NET Core Web API project from a .NET Framework Class Library project in the same solution?

I have a separate class library project(.NET Framework 4.8) to access the DB. This class library is written in Visual Basic(VB).
Recently, due to a new requirement, I had to add a web API layer into my solution to expose the data through endpoints.
I created a new .NET Core 2.1 Web API project in my existing solution. I configured the app settings in appSettings.json in .NET Core instead of App.config in .NET Framework as per the specifications.
Now the below code fails (I am not able to access my configuration settings).
Public connectionString As String = System.Configuration.ConfigurationManager.AppSettings("ConnectionString")
Error: system.typeinitializationexception
Note: This code was previously working. Not able to access the configuration settings.
Alternative tried: I tried to create a .NET Framework Web API (v4.8) instead of .NET Core Web API, and it worked. So, please provide me a solution to access the appSettings.json from .NET Core Web API project to .NET Framework Class Library (v4.8) which is written in VB.
How to access appSettings.json which belongs to a .NET Core Web API project from a .NET Framework Class Library project in the same solution
As we know, ASP.NET Core use different configuration settings. To achieve your above requirement, you can try following approaches:
Approach 1: modify your Class Library method(s) to accept additional parameter, then you can read ConnectionString etc from Web.config or appsettings.json and pass it as parameter while you call method within corresponding Apps.
Approach 2: modify and extend your Class Library to make it works with ASP.NET Core configuration settings, like below.
Imports System.Configuration
Imports Microsoft.Extensions.Configuration
Public Class DbGeneric
Private ReadOnly _configuration As IConfiguration
Public Sub New(ByVal configuration As IConfiguration)
_configuration = configuration
End Sub
Public Sub New()
End Sub
Public Function GetAll() As String
Dim connectionString As String = ConfigurationManager.ConnectionStrings("DefaultConnection").ConnectionString
Return connectionString
End Function
Public Function GetAllForCore() As String
Dim connectionString As String = _configuration("ConnectionStrings:DefaultConnection").ToString()
Return connectionString
End Function
End Class
In ASP.NET app
var dbGeneric = new MyClassLibraryVB.DbGeneric();
var con_str = dbGeneric.GetAll();
In ASP.NET Core app
public class ValuesController : ControllerBase
{
private readonly IConfiguration Configuration;
public ValuesController(IConfiguration configuration)
{
Configuration = configuration;
}
public IActionResult GetAll()
{
var dbGeneric = new MyClassLibraryVB.DbGeneric(Configuration);
var con_str = dbGeneric.GetAllForCore();
ConnectionStrings in appsettings.json
"ConnectionStrings": {
"DefaultConnection": "{conection_string_for_netcore}"
}
Test Result

Can we Host ASP.NET SignalR v2.4.1 in an ASP.NETCORE App?

I have a situation where my codebase is stuck in .Net 4.7.2 for now but I need to push some notifications on a Website which is built on Asp.Core 2.2.
Across the system we use SignalR 2.4.1 but it is completely re-written in .Net Core.
I tried hosting it in the same app without success. Owin does not seem to be happy.
Has anyone had any success with it or has any suggestion?
There has to be a way for projects migrating from .Net to Core.
Thanks
Ok so after along night I got a solution to this issue.
First just to make my setup clear.
There is an API project targetting .Net 4.7.2 which is broadcasting some messages via a SignalR 2.4.1 Hub.
There are some other Asp.Net 4.7.2 Projects consuming those Hubs which are working fine.
And also there is a new website build in .Net Core but targetting 4.7.2 framework.
The solution I ended up is essentially hosting an OWIN pipeline within the AspCore Pipeline.
First I needed to install the following packages:
Microsoft.Owin
Microsoft.AspNetCore.Owin
I also added a new extension method for the Core IApplicationBuilder interface that sets up OWIN on the same pipeline:
public static class OwinExtensions
{
public static IApplicationBuilder UseOwinApp(this IApplicationBuilder app, Action<IAppBuilder> configuration)
{
return app.UseOwin(setup => setup(next =>
{
IAppBuilder owinApp = new AppBuilder();
var aspNetCoreLifetime = (IApplicationLifetime)app.ApplicationServices.GetService(typeof(IApplicationLifetime));
var owinAppProperties = new AppProperties(owinApp.Properties)
{
OnAppDisposing = aspNetCoreLifetime?.ApplicationStopping ?? CancellationToken.None,
DefaultApp = next
};
configuration(owinApp);
return owinApp.Build<Func<IDictionary<string, object>, Task>>();
}));
}
}
Then in the Startup class of the Core project, in the Configure method I was able to use my extension and register SignalR hubs to it like this:
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseOwinApp(owinApp =>
{
owinApp.MapSignalR();
});
...
}
This way we can add more middlewares to the OWIN pipeline if we need to for whatever reasons.
I hope this helps.

.Net Core : Class Library to connect to DB, DAL, User Secret and Asp.Net Core's Configuration

I have the following :
a class library with connection classes such as connection, command, parameter
a DAL with entities, mapper, interface, services as well as a static class that holds hard coded connectionString and InvariantName.
an Asp.Net Core project
References :
DAL has a reference to the class library to make use of its connection class to which it provides connectionString and InvariantName thanks to its static class etc..
Asp.Net has a reference to the DAL.
What I want :
I now want to use the User Secrets to store hard coded sensitive data connections and get rid off the static class.
I know I can use the the Asp.Net Core startup.cs to read the settings from Configuration and make use of binding to store them into a class and use DI.
My guess :
DI seems "easy" when used inside an Asp controller. But I need the settings values (connectionString and InvariantName) outside the Asp.Net Core to be injected into a constructor of a class somewhere in my DAL.
I guess I would then need to have to reference the Asp.Net Core project to my DAL. But then I would end up with a circular reference (DAL to Asp.Net Core and the opposite).
So what's the solution?
Have an intermediate library class into which I would retreive the settings values from Asp.Net Core and then pass them to my DAL (to prevent circular reference)?
Manually recreate the "Configuration process" inside the DAL and get settings there directly
Or something else that I don't know?
Ps : I am new in development and only have a few projects'experience in Asp.Net Framework so far..and it's my first Asp.Net Core project
I know I can use the the Asp.Net Core startup.cs to read the settings from Configuration and make use of binding to store them into a class and use DI
You already answered your own question with this. This is the correct and recommended behavior to setup DI for 3rd party libs and configurations. If you want to avoid clutter in Startup class, create an extension method:
namespace Microsoft.Extensions.DependencyInjetion
{
public static MyLibraryCollectionExtensions
{
public static IServiceCollection AddMyLibrary(this IServiceCollection services)
{
services.AddDbContext<MyDbContext>(...);
}
}
}
to register your classes. Alternatively, extend the method to accept a parameter delegate to configure it
namespace Microsoft.Extensions.DependencyInjetion
{
public static MyLibraryCollectionExtensions
{
public static IServiceCollection AddMyLibrary(this IServiceCollection services, Action<MyOptions> setup)
{
var defaultOptions = ... // i.e. new MyOptions();
// pass default options to be modified by the delegate
setup?.Invoke(defaultOptions);
// your registrations
services.AddDbContext<MyDbContext>(...);
}
}
}
And all the user has to do in your library is add
services.AddMyLibrary();
// or with setup
services.AddMyLibrary(config =>
{
config.MyConnectionString = Configuration.GetConnectionString("MyContext");
});
and store the connection string in the appsettings.json.
{
"ConnectionStrings":
{
"MyContext" : "MyConnectionString here"
}
}
I finally used the ConfigurationBuilder to get values from the appsettings.json file.
It's probably not the right way to do it but it is working with my DAL and Connection dlls.
In case it helps anyone else :

How to add global metadata to ASP.NET Core logging?

I'd like to add my app's build number to all logs in an ASP.NET Core 3.1 app that is using Application Insights for log storage. Is this possible without having to use BeginScope and EndScope everywhere? I assumed it would be part of the ConfigureLogging startup hook, but didn't see anything. I've done this in the past with Serilog's enrichers, but am not using that library currently.
You can achieve that with TelemetryInitializer. (https://learn.microsoft.com/en-us/azure/azure-monitor/app/api-filtering-sampling#addmodify-properties-itelemetryinitializer)
public class BuildNumberTelemetryInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
(telemetry as ISupportProperties).Properties.Add("BuildNumber", "ValueForBuildNumber");
}
You need to add this initializer to the config, which is done like below if you are on Asp.Net Core applications.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ITelemetryInitializer, BuildNumberTelemetryInitializer >();
}

ConnectionString from appsettings.json in Data Tier with Entity Framework Core

I have a new application that I am building on ASP.NET Core with Entity Framework Core. The application has a UI, model, business, and data tier. In previous versions of ASP.NET, you could set the connection string in the web.config and it would be available in referenced tiers by default. This does not appear to be the same case in ASP.NET Core with appsettings.json (or other config options)? Any idea on how this is accomplished? I have the dbcontext configured in the data layer, but I am current hard-coding the connection string.
All examples I have see out there has the dbcontext configured in the UI layer in startup.cs. This is what I am trying to avoid.
The question Here got off topic.
You can easily add an extension method of IServiceCollection into your business/services layer and use it to register its own dependencies. Then in the startup you just call the method on the service layer without having any reference to EntityFramework in your web app.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace your.service.layer
{
public static class MyServiceCollectionExtensions
{
public static IServiceCollection AddMyServiceDependencies(this IServiceCollection services, string connectionString)
{
services.AddEntityFrameworkSqlServer()
.AddDbContext<YourDbContext>((serviceProvider, options) =>
options.UseSqlServer(connectionString)
.UseInternalServiceProvider(serviceProvider)
);
return services;
}
}
}
Startup:
using your.service.layer;
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("EntityFrameworkConnectionString");
services.AddMyServiceDependencies(connectionString);
}
Now your web app only needs a reference to your business/service layer and it is not directly dependent on EntityFramework.