C#-ReactiveUI依赖注入构造函数
作者:互联网
我在ReactiveUI中使用内置的依赖项注入器/ splat注入器.
我有要传递其适用的数据存储库的构造函数.
在其他框架中,它仅对接口使用反射,并使用GetServices调用来满足那些构造函数要求.例如,目前我具有用于创建类的此辅助程序扩展方法:
/// <summary>
/// Helper class for having a object's constructor automatically assigned by a "GetService" request.
/// </summary>
/// <param name="resolver">The resolver.</param>
/// <param name="type">The type to register.</param>
public static void Register<TConcrete, TInterface>(this IMutableDependencyResolver resolver)
where TConcrete : class
{
var concreteType = typeof(TConcrete);
// Must be a single constructor
var constructors = concreteType.GetConstructors().Single();
IList<object> values = new List<object>();
foreach (var parameter in constructors.GetParameters())
{
if (parameter.ParameterType.IsInterface == false)
{
throw new InvalidOperationException($"The type {concreteType.Name} has constructor paramters that are not interfaces.");
}
values.Add(resolver.GetService(parameter.ParameterType));
}
resolver.Register(() => Activator.CreateInstance(concreteType, values.ToArray()), typeof(TInterface));
}
之所以使用该帮助器类,是为了避免在AppBootStrapper中执行以下操作:
dependencyResolver.Register(() => new SetupFlightViewModel(dependencyResolver.GetService<IScreen>(), dependencyResolver.GetService<IFlightsModel>(), dependencyResolver.GetService<IAirportsModel>()), typeof(ISetupFlightViewModel));
只需检查以确保我没有对Splat / ReactiveUI框架做任何明显的事情,并且已经提供了它.我意识到执行上述操作会降低性能,并且可能会使用Expression Tree编译的表达式来避免每次或某些情况下的反射开销.
谢谢你的帮助,
格伦
解决方法:
Splat依赖项解析器(服务注册表)非常简单,开箱即用,并且不提供依赖项注入(DI).
但是,如果您喜欢DI(并不是每个人都喜欢,因为它可以隐藏依赖关系和设计复杂性,某些人会更愿意避免这种痛苦以更好地避免它),您可以像刚才那样轻松地将DI插入其中.
不过,对您的隐含评论之一,我建议您将对GetService的实际调用延迟到创建对象之前(以防您的服务注册表内容随时间变化,并避免强制注册顺序),例如:
var paramType = parameter.ParameterType;
values.Add(() => resolver.GetService(paramType));
... Activator.CreateInstance(concreteType, values.Select(cb => cb()).ToArray()) ...
标签:splat,reactiveui,c 来源: https://codeday.me/bug/20191027/1947937.html