想知道,是否可以在startup.cs之外访问IApplicationBuilder属性?像在控制器中一样?
我知道它仅用于定义应用程序管道,那么解决方案是什么?诸如注册打包实例的服务,然后注入服务而不是IApplicationBuilder的东西?
我正试图从Autofac找回我的DbConext。代码如下:
在Business
项目中:
public class AutofacBusinessModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterModule(new AutofacDataModule());
}
}
在数据项目中:
public class AutofacDataModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AppDbContext>().InstancePerLifetimeScope();
}
}
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();
}
}
以及Web项目中ConfigureServices
中的startup.cs
:
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);
}
我肯定会丢失一些东西,但是当涉及到DI和.net核心时真的是新手...
-编辑-
在我的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);
}
在GenerateExcelFile
方法中:
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);
}
}
但是当我运行该应用程序时,我收到此消息:
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Builder.IApplicationBuilder' while attempting to activate 'Cri.CodeGenerator.Web.Controllers.UniqueCodesController'.
答案 0 :(得分:1)
不,据我所知,这是不可能的。
您将必须编写中间件(或一些其他代码)才能将数据从IApplicationBuilder传递到HttpContext实例。
然后可以从控制器内部访问HttpContext实例。
希望这会有所帮助。
答案 1 :(得分:1)
听起来像您正在尝试获取AppDbContext
的新实例。
如果您必须将GenerateExcelFile()
保留为static
,并想通过参数重用AppDbContext
,则可以使其接受AppDbContext
的实例而不是{ {1}}。
首先,只需直接注入这样的服务实例:
IApplicationBuilder
然后更改 private readonly IHostingEnvironment _hostingEnvironment;
private readonly AppDbContext _dbContext;
// ...
public UniqueCodesController(IHostingEnvironment hostingEnvironment, AppDbContext dbContext)
{
_hostingEnvironment = hostingEnvironment;
_dbContext = dbContext;
}
以接受参数GenerateExcelFile()
public static async Task GenerateExcelFile(IApplicationBuilder app, IEnumerable<string>hashSetCodes, ContestViewModel model)public static async Task GenerateExcelFile(AppDbContext dbContext, IEnumerable hashSetCodes, ContestViewModel model) { ... try{var context = app.ApplicationServices.GetRequiredService();var contest = new Contest { Name = model.ProjectName, UserId = 1, FileGenerationStatus = true, FilePath = fileInfo.FullName };context.Contests.Add(contest);context.Contests.Add(contest); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
最后,您可以按以下方式调用它:
AppDbContext
请注意,如果在编译时无法确定所需的类型,并且想动态解析某些服务类型,则您可以注入 await FilesGenerationUtils.GenerateExcelFile(_dbContext, uniqueCodesHashSet, model);
而不是{{1} } 。这样,您可以根据需要解析任何实例:
IServiceProvider
以您的代码为例,您可以将IApplicationBuilder
传递给 var dbContext= sp.GetRequiredService<AppDbContext>();
// or if you need a service only available within a scope
using(var scope = this._sp.CreateScope()){
var _anotherDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
...
}
,在IServiceProvider
方法中,可以通过以下方式解析GenerateExcelFile(IServiceProvider sp, IEnumerable<string> hashSetCodes, ContestViewModel model)
:
GenerateExcelFile()