我正在将项目从 .Net Framework 迁移到 .Net Core。在现有的项目中,我们有一个实用程序类,其中包含一些功能,如下所示:
public static class BudgetUtilities
{
public static decimal CalculateBudgetRemaining(string fiscalYear = null)
{
if (string.IsNullOrWhiteSpace(fiscalYear))
fiscalYear = DateTime.Now.GetFiscalYear().ToString();
using (AppContext _context = new AppContext())
{
FiscalYearBudget currentBudget = _context.FiscalYearBudgets.Find(fiscalYear);
return currentBudget.BudgetAllocation - currentBudget.ExpenditureToDate;
}
}
// other functions removed for brevity
}
然后我可以使用 BudgetUtilities.CalculateBudgetRemaining()
在其他任何地方引用它。非常简单明了。
当将此函数迁移到 .Net Core 时,我需要使用依赖注入(inject),因此我通过删除 static 修饰符(因为静态构造函数不能有参数)并将 AppContext 注入(inject)到构造函数中来修改该类:
public class BudgetUtilities
{
private readonly AppContext _context;
public BudgetUtilities(AppContext context)
{
_context = context;
}
public decimal CalculateBudgetRemaining(string financialYear = null)
{
if (string.IsNullOrWhiteSpace(fiscalYear))
fiscalYear = DateTime.Now.GetFiscalYear().ToString();
FiscalYearBudget currentBudget = _context.FiscalYearBudgets.Find(fiscalYear);
return currentBudget.BudgetAllocation - currentBudget.ExpenditureToDate;
}
}
然后我尝试通过执行以下操作来调用我的代码:
BudgetUtilities utils = new BudgetUtilities();
decimal remaining = utils.CalculateBudgetRemaining();
但是如果不在构造函数中提供 AppContext,我就无法创建 BudgetUtilities 的新实例,这是有意义的。此应用程序中的每个方法都在某个时刻由 Controller 操作启动,并且我知道 DbContext
应该是短暂的,因此我假设将上下文从头到尾传递到此 BudgetUtilities 类初始 Controller 是一个坏主意。
我能看到的唯一其他选项是继续从引用 CalculateBudgetRemaining()
的地方返回调用堆栈,并继续添加构造函数注入(inject),直到到达 Controller ,但这不是我必须像这样注入(inject)唯一的类,因此我的构造函数在链上会变得非常臃肿,这将使我的 ConfigureServices()
方法也变得臃肿。
我确信有一种简单的方法可以做到这一点,但我就是看不到它。
最佳答案
不要手动创建新的 BudgetUtilities
实例,该类型也应该在 DI 框架中注册,最好是接口(interface):
public interface IBudgetUtilities
{
decimal CalculateBudgetRemaining(string financialYear);
}
public class BudgetUtilities : IBudgetUtilities
然后在 Startup.cs 中:
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddScoped<IBudgetUtilities, BudgetUtilities>();
}
然后它可以被注入(inject)到任何需要它的类中,例如 Controller :
public class YourController : Controller
{
private readonly IBudgetUtilities _utils;
public YourController(IBudgetUtilities utils)
{
_utils = utils;
}
public ActionResult YourMethod()
{
//...
decimal remaining = _utils.CalculateBudgetRemaining();
}
}
默认情况下,注册的 DbContexts
具有限定的生命周期,这意味着单个实例用于整个 HTTP 请求。
关于c# - 如何使用 MS.DI 和 .NET Core 从静态方法重构为依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61323366/