我试图使用通用的Lazy类来实例化.net核心依赖注入扩展的昂贵类。我已经注册了IRepo类型,但是我不确定Lazy类的注册是什么样的,或者是否支持它。作为一种解决方法,我使用了这种方法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<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<IRepo>
对象的工厂方法添加注册。
public void ConfigureService(IServiceCollection services)
{
services.AddTransient<IRepo, Repo>();
services.AddTransient<Lazy<IRepo>>(provider => new Lazy<IRepo>(provider.GetService<IRepo>));
}
我今天在我的部分代码中使用了上面的Lazier技术,但是当我想使用时,我发现我必须将其删除
IEnumerable<Lazy<ISomething>>
注册:
services.AddLazier();
services.AddTransient<ISomething, SomeThing1>();
services.AddTransient<ISomething, SomeThing2>();
注射:
public class IndexModel : PageModel
{
private IEnumerable<ISomething> _someThings;
private IEnumerable<Lazy<ISomething>> _someLazyThings;
public IndexModel(IEnumerable<ISomething> someThings,
IEnumerable<Lazy<ISomething>> someLazyThings)
{
_someThings = someThings;
_someLazyThings = someLazyThings;
}
public void OnGet()
{
List<string> names = new List<string>();
var countSomeThings = _someThings.Count(); // 2 as expected
var countSomeLazyThings = _someLazyThings.Count(); // 1. huh?
foreach (var lazyObject in _someLazyThings)
{
names.Add(lazyObject.Value.Name);
}
}
}
我还没有深入挖掘资料来找出我为什么不能获得2
IEnumerable<Lazy<ISomething>>
与
//services.AddLazier();//REMOVED
services.AddTransient<ISomething, SomeThing1>();
services.AddTransient<ISomething, SomeThing2>();
services.AddLazyTransient<ISomething, SomeThing1>();
services.AddLazyTransient<ISomething, SomeThing2>();
结果(按我的意思工作)..
public class IndexModel : PageModel
{
private IEnumerable<ISomething> _someThings;
private IEnumerable<Lazy<ISomething>> _someLazyThings;
public IndexModel(IEnumerable<ISomething> someThings,
IEnumerable<Lazy<ISomething>> someLazyThings)
{
_someThings = someThings;
_someLazyThings = someLazyThings;
}
public void OnGet()
{
List<string> names = new List<string>();
var countSomeThings = _someThings.Count(); // 2 as expected
var countSomeLazyThings = _someLazyThings.Count(); // 2 as expected
foreach (var someLazyThing in _someLazyThings)
{
names.Add(someLazyThing.Value.Name);
}
}
}
下面的IServiceCollection扩展显示了我如何注册服务。
foreach (var exchange in exchanges)
{
services.AddTransient<Lazy<ITokenExchangeHandler>>(serviceProvider =>
{
return new Lazy<ITokenExchangeHandler>(() =>
{
var tokenExchangeHandler = serviceProvider.GetRequiredService<PipelineTokenExchangeHandler>();
tokenExchangeHandler.Configure(exchange);
return tokenExchangeHandler;
});
});
}
public static class AspNetCoreServiceCollectionExtensions
{
public static IServiceCollection AddLazyTransient<TService, TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{
services.AddTransient<TImplementation>();
services.AddTransient<Lazy<TService>>(serviceProvider =>
{
return new Lazy<TService>(() =>
{
var impl = serviceProvider.GetRequiredService<TImplementation>();
return impl;
});
});
return services;
}
}