.net core依赖注入是否支持Lazy<T>
Does .net core dependency injection support Lazy<T>
我正在尝试使用通用 Lazy class 来实例化具有 .net 核心依赖项注入扩展的昂贵 class。我已经注册了 IRepo 类型,但我不确定 Lazy class 的注册会是什么样子,或者它是否受支持。作为解决方法,我使用了这种方法 http://mark-dot-net.blogspot.com/2009/08/lazy-loading-of-dependencies-in-unity.html
配置:
public void ConfigureService(IServiceCollection services)
{
services.AddTransient<IRepo, Repo>();
//register lazy
}
控制器:
public class ValuesController : Controller
{
private Lazy<IRepo> _repo;
public ValuesController (Lazy<IRepo> repo)
{
_repo = repo;
}
[HttpGet()]
public IActionResult Get()
{
//Do something cheap
if(something)
return Ok(something);
else
return Ok(repo.Value.Get());
}
}
您只需要为创建 Lazy<IRepo>
对象的工厂方法添加注册。
public void ConfigureService(IServiceCollection services)
{
services.AddTransient<IRepo, Repo>();
services.AddTransient<Lazy<IRepo>>(provider => new Lazy<IRepo>(provider.GetService<IRepo>));
}
这是另一种支持 Lazy<T>
通用注册的方法,这样任何类型都可以延迟解析。
services.AddTransient(typeof(Lazy<>), typeof(Lazier<>));
internal class Lazier<T> : Lazy<T> where T : class
{
public Lazier(IServiceProvider provider)
: base(() => provider.GetRequiredService<T>())
{
}
}
要在Lazy中获取的服务将通过工厂注册方法重新引入预期服务类型的新 Lazy 并使用 serviceProvider.GetRequiredService.
为其实现提供
services.AddTransient<IRepo, Repo>()
.AddTransient(serviceProvider => new Lazy<IRepo>(() => serviceProvider.GetRequiredService<IRepo>()));
在我看来,下面的代码应该可以完成工作(.net core 3.1)
services.AddTransient<IRepo, Repo>();
services.AddTransient(typeof(Lazy<>), typeof(Lazy<>));
将服务注册为懒惰
services.AddScoped<Lazy<AService>>();
services.AddScoped<Lazy<BService>>();
或者通过创建扩展程序
static class LazyServiceCollection
{
public static void AddLazyScoped<T>(this IServiceCollection services)
{
services.AddScoped<Lazy<T>>();
}
}
...
services.AddLazyScoped<AService>();
services.AddLazyScoped<BService>();
并使用它
[ApiController, Route("lazy")]
public class LazyController : ControllerBase
{
private readonly Lazy<AService> _aService;
private readonly Lazy<BService> _bService;
public LazyController(Lazy<AService> aService, Lazy<BService> bService)
{
_aService = aService;
_bService = bService;
}
[HttpGet("a")]
public ActionResult GetA()
{
_aService.Value.DoWork();
return new OkResult();
}
[HttpGet("b")]
public ActionResult GetB()
{
_bService.Value.DoWork();
return new OkResult();
}
}
结果
Init AService
AService Work
我正在尝试使用通用 Lazy class 来实例化具有 .net 核心依赖项注入扩展的昂贵 class。我已经注册了 IRepo 类型,但我不确定 Lazy class 的注册会是什么样子,或者它是否受支持。作为解决方法,我使用了这种方法 http://mark-dot-net.blogspot.com/2009/08/lazy-loading-of-dependencies-in-unity.html
配置:
public void ConfigureService(IServiceCollection services)
{
services.AddTransient<IRepo, Repo>();
//register lazy
}
控制器:
public class ValuesController : Controller
{
private Lazy<IRepo> _repo;
public ValuesController (Lazy<IRepo> repo)
{
_repo = repo;
}
[HttpGet()]
public IActionResult Get()
{
//Do something cheap
if(something)
return Ok(something);
else
return Ok(repo.Value.Get());
}
}
您只需要为创建 Lazy<IRepo>
对象的工厂方法添加注册。
public void ConfigureService(IServiceCollection services)
{
services.AddTransient<IRepo, Repo>();
services.AddTransient<Lazy<IRepo>>(provider => new Lazy<IRepo>(provider.GetService<IRepo>));
}
这是另一种支持 Lazy<T>
通用注册的方法,这样任何类型都可以延迟解析。
services.AddTransient(typeof(Lazy<>), typeof(Lazier<>));
internal class Lazier<T> : Lazy<T> where T : class
{
public Lazier(IServiceProvider provider)
: base(() => provider.GetRequiredService<T>())
{
}
}
要在Lazy中获取的服务将通过工厂注册方法重新引入预期服务类型的新 Lazy 并使用 serviceProvider.GetRequiredService.
为其实现提供services.AddTransient<IRepo, Repo>()
.AddTransient(serviceProvider => new Lazy<IRepo>(() => serviceProvider.GetRequiredService<IRepo>()));
在我看来,下面的代码应该可以完成工作(.net core 3.1)
services.AddTransient<IRepo, Repo>();
services.AddTransient(typeof(Lazy<>), typeof(Lazy<>));
将服务注册为懒惰
services.AddScoped<Lazy<AService>>();
services.AddScoped<Lazy<BService>>();
或者通过创建扩展程序
static class LazyServiceCollection
{
public static void AddLazyScoped<T>(this IServiceCollection services)
{
services.AddScoped<Lazy<T>>();
}
}
...
services.AddLazyScoped<AService>();
services.AddLazyScoped<BService>();
并使用它
[ApiController, Route("lazy")]
public class LazyController : ControllerBase
{
private readonly Lazy<AService> _aService;
private readonly Lazy<BService> _bService;
public LazyController(Lazy<AService> aService, Lazy<BService> bService)
{
_aService = aService;
_bService = bService;
}
[HttpGet("a")]
public ActionResult GetA()
{
_aService.Value.DoWork();
return new OkResult();
}
[HttpGet("b")]
public ActionResult GetB()
{
_bService.Value.DoWork();
return new OkResult();
}
}
结果
Init AService
AService Work