gpt4 book ai didi

c# - 如何在 Controller 中访问 IApplicationBuilder?

转载 作者:行者123 更新时间:2023-12-05 05:11:25 24 4
gpt4 key购买 nike

只是想知道,是否可以在 startup.cs 之外访问 IApplicationBuilder 属性?就像在 Controller 中一样?

我知道它仅用于定义应用程序管道,那么解决方案是什么?比如注册一个打包实例的服务,然后注入(inject)服务而不是 IApplicationBuilder?

我正在尝试从 Autofac 取回我的 DbConext。代码如下:

业务项目中:

 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项目中startup.cs中的ConfigureServices:

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'.

最佳答案

听起来您正在尝试获取 AppDbContext 的新实例.

如果您必须保留 GenerateExcelFile()作为static并想重复使用AppDbContext通过一个参数,你可以让它接受 AppDbContext 的实例而不是 IApplicationBuilder .

首先,简单地直接注入(inject)这样一个服务实例:

    private readonly IHostingEnvironment _hostingEnvironment;
private readonly AppDbContext _dbContext;

// ...

public UniqueCodesController(IHostingEnvironment hostingEnvironment, AppDbContext dbContext)
{
_hostingEnvironment = hostingEnvironment;
_dbContext = dbContext;
}

然后更改GenerateExcelFile()接受 AppDbContext 的参数

    
  
   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);        }    }

Finally, you could invoke it as below :

    await FilesGenerationUtils.GenerateExcelFile(_dbContext, uniqueCodesHashSet, model);

作为旁注,如果您无法在编译时确定所需的类型,并希望动态解析某些服务类型,您可以注入(inject)一个 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>();
...
}

以您的代码为例,您可以传递 IServiceProviderGenerateExcelFile(IServiceProvider sp, IEnumerable<string> hashSetCodes, ContestViewModel model) ,并在 GenerateExcelFile() 内方法,你可以解决 AppDbContext通过以下方式:

    public static async Task GenerateExcelFile(IServiceProvider sp, IEnumerable<string> hashSetCodes, ContestViewModel model)
{
...

var dbContext= sp.GetRequiredService<AppDbContext>();

try{
var contest = new Contest
{
Name = model.ProjectName,
UserId = 1,
FileGenerationStatus = true,
FilePath = fileInfo.FullName
};

dbContext.Contests.Add(contest);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

}

关于c# - 如何在 Controller 中访问 IApplicationBuilder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55462128/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com