用来自另一个已注册 object 的另一个 属性 的值注入 属性?

Inject property with value from another property of another registered object?

我不太确定 DryIoc 是否值得我花时间。它看起来很轻巧,并且在 cross-platform 环境(使用 Xamarin)中得到很好的支持。但是我觉得使用它有点困难(就我自己探索一切而言)。

DryIoc 社区也不是很大(通过阅读有关 DryIoc 的一些答案,我认识到看起来只有作者跳进来并给出答案)。这是标题中提到的我的问题。假设我有 2 个 ViewModel 类,第二个有一个 属性,它应该始终与第一个的 属性 匹配(映射),如下所示:

public class ParentViewModel {
}
public class FirstViewModel {
   public FirstViewModel(ParentViewModel parent){
   }
   public string A {
      //...
   }
}
public class SecondViewModel {
   public SecondViewModel(ParentViewModel parent){
   }
   public string A {
      //...
   }
}

现在我可以使用 dryioc 为两个 ViewModel 注册单例,但对于第二个,我还需要注入 属性 A 以及第一个 属性 A 的值。

container.Register<ParentViewModel>();
container.Register<FirstViewModel>(reuse: Reuse.Singleton, made: Made.Of(() => new FirstViewModel(Arg.Of<ParentViewModel>())));
container.Register<SecondViewModel>(reuse: Reuse.Singleton, made: Made.Of(() => new SecondViewModel(Arg.Of<ParentViewModel>())));

正如您所见,第一次注册应该没问题,因为不需要 属性 依赖项。但是第二个应该有它的 A 属性 取决于第一个的 A

真的我无法自己探索这个。注入一些注册类型的属性没问题(至少我知道怎么做),但这里注入的值是另一个 属性 某种注册类型

这是实现该目标的 straightforward way(但可能不是最好的):

using System;
using DryIoc;

public class Program
{
    public static void Main()
    {
        var container = new Container();

        container.Register<ParentViewModel>();

        container.Register<FirstViewModel>(Reuse.Singleton);

        container.Register<SecondViewModel>(Reuse.Singleton, 
            made: PropertiesAndFields.Of.Name("A", r => r.Container.Resolve<FirstViewModel>().A));

        var firstVM = container.Resolve<FirstViewModel>();
        firstVM.A = "blah";

        var secondVM = container.Resolve<SecondViewModel>();

        Console.WriteLine(secondVM.A); // should output "blah"
    }

    public class ParentViewModel {
    }

    public class FirstViewModel {
       public FirstViewModel(ParentViewModel parent) { }
       public string A { get; set; }
    }

    public class SecondViewModel {
       public SecondViewModel(ParentViewModel parent) {}
       public string A { get; set; }
    }
}

在我看来,更好更简单的方法是控制反转:在两个虚拟机之外创建 A,然后将它们注入到两个虚拟机中。