繁体   English   中英

Unity 到 DryIoC 的转换 ParameterOverride

[英]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);
    }
}

问题未解决?试试以下方法:

Unity 到 DryIoC 的转换 ParameterOverride

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM