依赖注入基础知识
几乎任何控制器都需要一些外部依赖项才能工作。这是一种配置依赖项对象(或其工厂)并将其传递给控制器的方法。这样做有助于维持关注点分离 ,保持代码清晰可测。
比如说,我们有一个接口及其实现,需要在其构造函数中使用 config 中的一些值:
public interface ISomeDependency
{
async Task<IEnumerable<string>> GetItemsAsync(string key);
}
public class SomeDependency : ISomeDependency
{
public SomeDependency(string connectionString)
{
...
}
...
}
它用在某些控制器类中:
public class SomeController : Controller
{
private reanonly ISomeDependency dependency;
public SomeController(ISomeDependency dependency)
{
...
this.dependency = dependency;
}
...
public async Task<IEnumerable<string>> Get(string key) =>
await dependency.GetItemsAsync(key);
}
可以在 Startup.ConfigureServices
方法中调用 services.AddTransient
的控制器构造函数中注入此依赖项:
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder().
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
...
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
...
services.AddTransient(serviceProvider =>
new MyDependency(Configuration["Data:ConnectionString"]));
}
...
}
这里 Data:ConnectionString
是 appsettings.json
文件中设置的路径:
{
...
},
"Data": {
"ConnectionString": "some connection string"
}
}
终身管理
为了管理注入对象的生命周期,与 AddTransient
一起存在另外两个选项:AddSingleton
和 AddScoped
。最后一个意味着对象的生命周期限定为 HTTP 请求。