【发布时间】:2019-08-23 00:47:41
【问题描述】:
只是想知道,是否可以在 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();
}
}
还有 ConfigureServices 在 Web 项目中的 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'.
【问题讨论】:
-
通常当你在 DI 中注册了一些东西时,你将它作为参数添加到构造函数中,所以在这种情况下你的控制器的构造函数。
-
通常你会把依赖放在控制器的构造函数中,让DI容器解决它。那不工作吗?您到底在哪里认为需要 IApplicationBuilder?你还没有展示这个,所以理解这个问题有点困难。如果您尝试过但没有成功,请提供更多详细信息,例如是否存在异常或其他一些意外行为?乍一看,这里的一切看起来都很合理。
-
@MikeZboray 我刚刚更新了原始帖子,以显示我正在尝试做的事情以及尝试时得到的结果。谢谢你的时间:)
标签: c# asp.net-core dependency-injection autofac