[英]Unity to DryIoC conversion ParameterOverride
我们正在从 Xamarin.Forms 过渡到 .Net MAUI,但我们的项目使用 Prism.Unity.Forms。 我们有很多代码基本上使用 IContainer.Resolve() 传递带有一些原语的 ParameterOverrides 集合,但有些是接口/对象。 我们正在解析的 T 通常是一个已注册的视图,它可能是也可能不是这样做的正确方法,但这是我正在使用的,我们正在后端代码(有时是服务)中进行。 在 DryIoC 中执行此 Unity 操作的正确方法是什么? 请注意,这些参数是在运行时设置的,可能只是构造函数接受的参数的一部分(有些可能来自已经注册的依赖项)。
场景示例:
//Called from service into custom resolver method
var parameterOverrides = new[]
{
new ParameterOverride("productID", 8675309),
new ParameterOverride("objectWithData", IObjectWithData)
};
//Custom resolver method example
var resolverOverrides = new List<ResolverOverride>();
foreach(var parameterOverride in parameterOverrides)
{
resolverOverrides.Add(parameterOverride);
}
return _container.Resolve<T>(resolverOverrides.ToArray());
您已经发现为什么不在解析根之外使用容器。 我建议不要尝试用另一个容器复制这个错误,而是修复它——使用手工编码的工厂:
internal class SomeFactory : IProductViewFactory
{
public SomeFactory( IService dependency )
{
_dependency = dependency ?? throw new ArgumentNullException( nameof(dependency) );
}
#region IProductViewFactory
public IProductView Create( int productID, IObjectWithData objectWithData ) => new SomeProduct( productID, objectWithData, _dependency );
#endregion
#region private
private readonly IService _dependency;
#endregion
}
也看到这个:
对于独立于您正在创建的实例的依赖项,将它们注入工厂并存储它们直到需要。
对于独立于创建上下文但需要为每个创建的实例重新创建的依赖项,将工厂注入工厂并存储它们。
对于依赖于创建上下文的依赖项,将它们传递到工厂的 Create 方法中。
此外,请注意容器行为中潜在的细微差别:Unity 的ResolverOverride
对整个解析调用起作用,即它们也覆盖依赖项的参数,无论碰巧按名称匹配。 DryIOC 可以很好地以非常不同的方式处理这一点。
首先,我同意@haukinger 的回答,重新考虑如何将运行时信息传递到服务中。 在我看来,最透明和最简单的方法是通过参数将其传递给使用方法。
其次,这里有一个完整的 DryIoc 示例,可以正面解决它 +可以玩的实时代码。
using System;
using DryIoc;
public class Program
{
record ParameterOverride(string Name, object Value);
record Product(int productID);
public static void Main()
{
// get container somehow,
// if you don't have an access to it directly then you may resolve it from your service provider
IContainer c = new Container();
c.Register<Product>();
var parameterOverrides = new[]
{
new ParameterOverride("productID", 8675309),
new ParameterOverride("objectWithData", "blah"),
};
var parameterRules = Parameters.Of;
foreach (var po in parameterOverrides)
{
parameterRules = parameterRules.Details((_, x) => x.Name.Equals(po.Name) ? ServiceDetails.Of(po.Value) : null);
}
c = c.With(rules => rules.With(parameters: parameterRules));
var s = c.Resolve<Product>();
Console.WriteLine(s.productID);
}
}
问题未解决?试试以下方法:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.