How to manage same named constructor - c#

Check my controller code bellow. The thing is i am using first AccountController to access my database context and second one want to access of my appsettings.json file with IConfiguration. But C# not giving to to name same named controller. So how can i access IConfiguration and database context at a time on same Controller file? Please note: I am using .net core mvc 2.1 Picture attached with error. Thanks in advance
Controller code:
public class AccountController : Controller
{
public AppDataCtx DataCtx { get; }
public AccountController(AppDataCtx DataCtx)
{
this.DataCtx = DataCtx;
}
private IConfiguration _configuration;
public IConfiguration AccountController(IConfiguration Configuration)
{
_configuration = Configuration;
}
}

Related

How to get ConnectionString Value from appsetting.json into Repository in Core WebAPI

I'm new to Net Core WebAPI, I'm developing Core Web API without EF. I got stuck were i'm not able to get Connection String from appsetting.json into my Repository
I have created Constructor of CommonRepository and used IConfiguration to get connection string value
public CommonRepository(IConfiguration configuration)
{
_configuration = configuration;
}
private readonly IConfiguration _configuration;
but while creating object of common repository it is giving an error
CommonRepository commonRepository =new CommonRepository();
There is no argument given that corresponds to the required formal parameter 'configuration' of 'CommonRepository.CommonRepository(IConfiguration)'
You could refer the following code to create and use the CommonRepository, then, get the connection string.
CommonRepository:
public interface ICommonRepository
{
string GetConnectionstring();
}
public class CommonRepository : ICommonRepository
{
private readonly IConfiguration _configuration;
public CommonRepository(IConfiguration configuration)
{
_configuration = configuration;
}
public string GetConnectionstring()
{
return _configuration.GetConnectionString("DefaultConnection");
}
}
Register the above repository in the Startup.ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddScoped<ICommonRepository, CommonRepository>();
}
Controller:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ICommonRepository _commonRepositoty;
public HomeController(ILogger<HomeController> logger, ICommonRepository commonRepository)
{
_logger = logger;
_commonRepositoty = commonRepository;
}
public IActionResult Index()
{
var str = _commonRepositoty.GetConnectionstring();
return View();
}
The result like this:
More detail information, see Dependency injection in ASP.NET Core.
This is normally done using dependency injection which should be setup in the startup.cs file. As such:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfiguration>(Configuration);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
}
}
ASP.Net will automatically pass in the config to this class from the host. We use this to create a singleton which will inject the config into all constructors that use IConfiguration as a parameter. Explained Here

Need a way to get the current request URL to configure the database context in multi-tenant application

I am migrating a web app from asp.net mvc to .net core (.net 5), and this has got me stuck.
The site is configured in IIS to accept request from multiple URLs like site1.example.com and site2.example.com. Each site has its own database, accessed through entity framework core.
In the old .net framework, I was able to use one of the events in the global.asax.cs to parse the incoming request URL and lookup the correct tenant database from a configuration file. I'm trying to set up something similar in asp.net core mvc.
Here's the relevant part of my ConfigureServices method in the startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddSingleton<ITenantIdentifier, UrlTenantIdentifier>();
services.AddDbContext<myDbContext>((serviceProvider, dbContextBuilder) =>
{
var tenantIdentifier = serviceProvider.GetRequiredService<ITenantIdentifier>();
var connectionString = Configuration.GetConnectionString(tenantIdentifier.GetCurrentTenantId() + "myDataModel");
dbContextBuilder.UseSqlServer(connectionString);
}, ServiceLifetime.Scoped);
//other services configured below...
}
Then the tenant identifier looks like this:
public interface ITenantIdentifier
{
string GetCurrentTenantId();
}
public class UrlTenantIdentifier : ITenantIdentifier
{
readonly IHttpContextAccessor _httpContextAccessor;
readonly ILogger<UrlTenantIdentifier> _logger;
public UrlTenantIdentifier(IHttpContextAccessor httpContextAccessor, ILogger<UrlTenantIdentifier> logger)
{
_httpContextAccessor = httpContextAccessor;
_logger = logger;
}
public string GetCurrentTenantId()
{
//_httpContextAccessor is null here
//logic below for parsing URL and finding if we're site1 or site2
}
}
Is there a correct way of doing this now that I'm not aware of? How can I set up the entity framework database context for dependency injection when I don't know the connection string key until runtime? Am I going to be stuck configuring separate sites and virtual directories in IIS?
Refactor the DbContext to override the OnConfiguring member. Inject configuration and context accessor and perform configuration there.
public class myDbContext : DbContext {
private readonly ITenantIdentifier tenantIdentifier;
private readonly IConfiguration configuration;
public myDbContext(IConfiguration configuration, ITenantIdentifier tenantIdentifier) {
this.configuration = configuration;
this.tenantIdentifier = tenantIdentifier;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
var connectionString = configuration
.GetConnectionString(tenantIdentifier.GetCurrentTenantId() + "myDataModel");
optionsBuilder.UseSqlServer(connectionString);
}
}
Trying to access the request context at the time the DbContext is being created/initialized is too early in the request flow to get access to the desired information. It needs to happen after the context has already been initialized and injected.
public void ConfigureServices(IServiceCollection services)
services.AddHttpContextAccessor();
services.AddSingleton<ITenantIdentifier, UrlTenantIdentifier>();
services.AddDbContext<myDbContext>(); //Simplified since configuration is internal
//other services configured below...
}
Reference DbContext Lifetime, Configuration, and Initialization

Getting the Base URL in ASP.Net Core

I've just recently switched over from ASP.NET MVC to using .Core 2 and I can't figure out how to get the current URL in Core. I could get it easily enough using the Request in previous asp.net versions, but since that's no long valid in .Net Core I'm at a loss.
I haven't been able to find any way from my google searching as of now.
Any help is appreciated. Thanks!
In the ConfigureServices method of your Startup.cs file, add the line:
services.AddHttpContextAccessor();
and you will now have access to the IHttpContextAccessor interface throughout your code when using dependency injection.
Usage as follows:
public class CustomerRepository
{
private readonly IHttpContextAccessor _context;
public CustomerRepository(IHttpContextAccessor context)
{
_context = context;
}
public string BaseUrl()
{
var request = _context.HttpContext.Request;
// Now that you have the request you can select what you need from it.
return string.Empty;
}
}
Hope this answers your question :)
Try:
public class Startup {
public Startup(IConfiguration configuration, IHostingEnvironment env) {
Configuration = configuration;
HostingEnvironment = env;
var url = configuration[WebHostDefaults.ServerUrlsKey];
}
Please note that you can get more than one url.

Get connection string in .NET Core application

I'm trying to get connection string dynamically from appsettings.json file. I see that I can do that via Configuration property of startup class. I've marked Configuration field as static field and access it across the app.
I'm wondering if there is a better way to get connection string value from .NET Core app.
You can check my blog article on ASP.NET Core Configuration here.
In it I also go through Dependency Injection of configuration options.
Quote:
There are a couple ways to get settings. One way would be to use the
Configuration object in Startup.cs.
You can make the configuration available in your app globally through
Dependency Injection by doing this in ConfigureServices in Startup.cs:
services.AddSingleton(Configuration);
You can do a thread-safe Singleton of your IConfiguration variable declared in the Startup.cs file.
private static object syncRoot = new object();
private static IConfiguration configuration;
public static IConfiguration Configuration
{
get
{
lock (syncRoot)
return configuration;
}
}
public Startup()
{
configuration = new ConfigurationBuilder().Build(); // add more fields
}
private readonly IHostingEnvironment _hostEnvironment;
public IConfiguration Configuration;
public IActionResult Index()
{
return View();
}
public ViewerController(IHostingEnvironment hostEnvironment, IConfiguration config)
{
_hostEnvironment = hostEnvironment;
Configuration = config;
}
and in class that you want connection string
var connectionString = Configuration.GetConnectionString("SQLCashConnection");

Using Configuration Settings in ASP.NET 5

I am learning about ASP.NET 5. One of the areas that has me really confused is configuration. For the life of me, I cannot figure out how to load a value from the configuration file in a class. Before ASP.NET 5, I would just use:
ConfigurationManager.AppSettings["KeyName"];
However, now with ASP.NET 5, I'm a little confused. Currently, I have the following in Startup.cs:
public IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment environment)
{
var configuration = new Configuration()
.AddJsonFile("config.json");
Configuration = configuration;
}
This seems to load the configuration settings just fine. However, lets say I have a class called "Customer.cs" which interacts with the database. The database connection string is in config.json. How do I get that value? It doesn't seem efficient to load "config.json" in all of my POCOs. At the same time, the approach above doesn't seem to allow me to access Configuration in a global manner.
How should I load configuration settings and retrieve the configuration values in my POCOs?
Thank you
You should not load the connection string in each POCO entity (Have you ever used a DB Context?). If you're using Entity Framework 7 you can load the database context service when your app starts.
If your config.json looks like this:
"Data": {
"DefaultConnection": {
"Connectionstring": "your_connection_string"
}
you can set up your environment like this:
public void ConfigureServices(IServiceCollection services)
{
// Add EF services to the services container
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<Your__DB__Context__Class>(options =>
options.UseSqlServer(Configuration.Get("Data:DefaultConnection:ConnectionString")));
}
//... other services...
}
Then in your controller you can directly use the DbContext through dependency injection:
public class Your__Controller : Controller
{
[FromServices]
public Your__DB__Context__Class DbContext { get; set; }
//...
}
If you need to use the DbContext service outside from the controller you have to do like this:
class NotAControllerClass : NotAController
{
private readonly Your__DB__Context__Class _dbContext;
public NotAControllerClass(Your__DB__Context__Class DbContext)
{
_dbContext = DbContext;
}
//do stuff here...
}
Finally if you're not using EF7 but instead a prevoious version of EF or a custom ORM you need a custom dependency injection. Try to search it on the internet.

Categories