gpt4 book ai didi

c# - 以编程方式注入(inject)依赖asp.net core

转载 作者:太空狗 更新时间:2023-10-29 22:57:22 25 4
gpt4 key购买 nike

我刚开始使用 Asp.net core 依赖注入(inject),我的概念可能不准确。 This docs.asp.net post解释了如何将上下文注入(inject) Controller 。从测试的角度来看,我对注入(inject)没有什么困惑。假设我们有以下场景:

public interface ITasksRepository
{
public void Create();
}

//This is fake implementation, using fake DbContext for testing purpose
public class TasksRepositoryFake : ITasksRepository
{
public void Create()
{
FakeDbContext.Add(sometask);
//logic;
}
}

//This is actual implementation, using actual DbContext
public class TasksRepository : ITasksRepository
{
public void Create()
{
DbContext.Add(someTask);
//logic;
}
}

现在为了在 Controller 中注入(inject)上下文,我们将其设计为:

public class TasksController : Controller
{
public ITasksRepository TaskItems { get; set; }

public TodoController(ITaskRepository taskItems)
{
TaskItems = taskItems;
}
//other logic
}

asp.net core 提供的内置功能是,我们可以在启动类中注册依赖注入(inject),如下所示:

public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddSingleton<ITasksRepository, TasksRepositoryFake>();
}

按照这个逻辑,我的TaskRepositoryFake会被注入(inject)到controller中。到目前为止,一切都很清楚。我对此的问题/困惑如下:

问题:

  • 我如何使用这个内置的 DI 功能通过一些逻辑注入(inject)上下文?可能以编程方式,或基于配置,或基于环境? (例如,在使用“测试”环境时总是注入(inject)假上下文?等)
  • 有可能吗?如果我们总是必须在 StartUp 类中手动更改它,那么这个内置的 DI 功能如何为我们服务?因为我们可以简单地在 Controller 中完成此操作,而无需此功能。

最佳答案

首先回答您的问题:是的,您可以通过编程方式注入(inject)依赖项。通过使用工厂,就像基于运行时值注入(inject)依赖项的情况一样。 AddSingleton 有一个重载,它需要一个 implementationfactory,因此您的用例的基本示例如下所示:

   public class Startup
{
public bool IsTesting { get; }

public Startup(IHostingEnvironment env)
{
IsTesting = env.EnvironmentName == "Testing";
}

// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ISomeRepository>(sp => IsTesting ? (ISomeRepository)new SomeRepository() : (ISomeRepository) new FakesomeRepository());
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, ISomeRepository someRepository)
{
app.UseIISPlatformHandler();

app.Run(async (context) =>
{
await context.Response.WriteAsync($"Hello World from {nameof(someRepository)}!");
});
}

// Entry point for the application.
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}

有关您的 TasksRepository 的代码行如下所示:

services.AddSingleton<ITaskRepository>(sp => isTesting?(ITasksRepository)new TasksRepositoryFake(): (ITasksRespository)new TasksRepository() );

更好的方法是将其放入工厂(再次以我的示例为例):

services.AddSingleton<ISomeRepository>(sp => SomeRepositoryFactory.CreatSomeRepository(IsTesting));

我希望您看到这如何帮助您设置基于配置、基于环境或您想要的方式。如果你感兴趣,我通过抽象工厂写了更多关于基于运行时值的 DI here .

话虽如此,通过单元测试,我会简单地将我的伪造注入(inject)到正在测试的类中。单元测试仍然可以向你自己和你的同事证明代码仍然按预期运行。 通过集成测试,我会用我所有的假货制作一个特殊的 StartUp 类,并将其提供给测试主机,因为 ASP.NET Core 允许您这样做。您可以在此处阅读有关测试主机的更多信息:https://docs.asp.net/en/latest/testing/integration-testing.html

希望这对您有所帮助。

更新 添加了强制转换到界面,因为三元条件无法判断。加上添加了一些基本示例。

关于c# - 以编程方式注入(inject)依赖asp.net core,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39065458/

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