Just wondering, is that possible to access IApplicationBuilder propteries outside of the startup.cs? Like in a controller?
I know it's only used to define the app pipeline so what would be the solution? Something like register a service that packages the instance, then inject the service instead of the IApplicationBuilder?
I'm trying to get back my DbConext from Autofac. Code is as following :
In Business
project :
public class AutofacBusinessModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterModule(new AutofacDataModule());
}
}
In Data project :
public class AutofacDataModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AppDbContext>().InstancePerLifetimeScope();
}
}
The DbContext
:
public class AppDbContext : DbContext
{
private const string DbContextName = "AppDbConnectionString";
public DbSet<Contest> Contests { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public AppDbContext()
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured) return;
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var connectionString = configuration.GetConnectionString(DbContextName);
optionsBuilder.UseSqlServer(connectionString,
x => x.MigrationsAssembly("Cri.CodeGenerator.Data"));
}
public virtual void Commit()
{
base.SaveChanges();
}
}
And the ConfigureServices
in startup.cs
in Web project :
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacBusinessModule());
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddScoped(sp => {
var actionContext = sp.GetRequiredService<IActionContextAccessor>().ActionContext;
var urlHelperFactory = sp.GetRequiredService<IUrlHelperFactory>();
var urlHelper = urlHelperFactory.GetUrlHelper(actionContext);
return urlHelper;
});
services.AddDistributedMemoryCache();
builder.Populate(services);
ApplicationContainer = builder.Build();
//return the IServiceProvider implementation
return new AutofacServiceProvider(ApplicationContainer);
}
I'm surely missing something, but really newbie when it comes to DI and .net core...
-- EDIT --
In my Controller
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IApplicationBuilder _app;
private const int NumberOfCharactersRepetion = 4;
public UniqueCodesController(IHostingEnvironment hostingEnvironment, IApplicationBuilder app)
{
_hostingEnvironment = hostingEnvironment;
_app = app;
}
...
if (selectedAnswer == FileExtension.XLSX.GetStringValue())
{
await FilesGenerationUtils.GenerateExcelFile(_app, uniqueCodesHashSet, model);
}
in the GenerateExcelFile
method :
public static async Task GenerateExcelFile(IApplicationBuilder app, IEnumerable<string> hashSetCodes, ContestViewModel model)
{
...
try
{
var context = app.ApplicationServices.GetRequiredService<AppDbContext>();
var contest = new Contest
{
Name = model.ProjectName,
UserId = 1,
FileGenerationStatus = true,
FilePath = fileInfo.FullName
};
context.Contests.Add(contest);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
But when I run the app, I get this message :
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Builder.IApplicationBuilder' while attempting to activate 'Cri.CodeGenerator.Web.Controllers.UniqueCodesController'.
NO, it is not possible as far as I know.
You will have to write a middleware (or some other code) to get the data from IApplicationBuilder to HttpContext instance.
Then HttpContext instance you can access from inside the controllers.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With