使用MS DI自动注册依赖项


services.AddSingleton<NavigationBarViewModel>();
services.AddSingleton<FileHandlingViewModel>();
services.AddSingleton<SchedulingProblemViewModel>();
....
services.AddSingleton<Func<FileHandlingViewModel>>((s) => () => s.GetRequiredService<FileHandlingViewModel>());
services.AddSingleton<Func<SchedulingProblemViewModel>>((s) => () => s.GetRequiredService<SchedulingProblemViewModel>());
services.AddSingleton<Func<TimeIntervalsViewModel>>((s) => () => s.GetRequiredService<TimeIntervalsViewModel>());
...

我注册一堆Func如上所示到MS DI容器。我可以列出与反射相关的类型。我可以自动注册类型,但我也想自动注册Funcforeach。有什么主意吗?

似乎在MS DI中无法完成工厂方法的自动注册。问题是,我们可以用MakeGenericMethod创建工厂方法,但这个方法仍然需要显式强制转换,我们不能在自动注册循环中使用。

解决方法:使用工厂类代替工厂方法。

public class PageViewModelFactory<TPageViewModel> where TPageViewModel : ViewModelBase
{
private readonly IServiceProvider services;
public PageViewModelFactory(IServiceProvider services)
{
this.services = services;
}
public TPageViewModel Create() => services.GetRequiredService<TPageViewModel>(); // Transient
}
var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes())
.Where(t => !t.IsInterface).ToList();
// auto-register all type which implements IPage
types.Where(t => typeof(IPage).IsAssignableFrom(t))
.ToList().ForEach(t => CreateAndAddClosedType(services, typeof(PageViewModelFactory<>), t));
private static void CreateAndAddClosedType(IServiceCollection services, Type openType, Type? type)
{
var typeArgs = new Type[] { type! };
var closedType = openType.MakeGenericType(typeArgs);
services.AddSingleton(closedType);
}

在Factory类中存储IServiceProvider似乎是服务定位器反模式,但当我们手动注册一个函数时,MS DI也会这样做。现在我们可以用PageViewModelFactory<FileHandlingViewModel>.Create代替Func<FileHandlingViewModel>

最新更新