简体   繁体   中英

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

I'm not so sure that DryIoc is worth my time. It looks like lightweight and supported well in cross-platform environment (with Xamarin). But I feel a bit difficult working with it (in term of exploring everything myself).

The DryIoc community is also not very large (and by reading through some answers about DryIoc, I recognized that looks like there is only the author jumping in and giving the answers). Here is my problem as mentioned in the title. Suppose I have 2 ViewModel classes, the second has a property which should always match (mapped) with a property of the first, like this:

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

Now I can use dryioc to register singleton for both ViewModels BUT for the second one, I also need to inject the property A with value from the first's property A as well.

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>())));

So as you can see the first registration should be fine because no property dependency is required. However the second one should have its A property depend on the A of the first one.

Really I cannot explore this myself. Injecting properties of some registered type is fine (and at least I know how to do that), but here the injected value is another property of some registered type .

Here is the straightforward way (but may be not the best one) to achieve that:

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; }
    }
}

In my opinion, the better and more simple way will the inversion of control: creating the A outside of both VMs and then injecting them into both.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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