Search code examples
dryioc

Injecting interface intoViewmodel is null


My knowledge of DryIoc is limited and I hope somebody can help me. In my mobile app I am reading a json file that contains all my settings

I would like to inject only the relevant settings to the relevant viewmodel.

Basically how do Inject my populated object/interface into the constructor of the viewmodel

Below is a noddy test and sample that fails at the moment.

I could set the property of the viewmodel but I would like the interface not to be null when the viewmodel constructor is called.

Hope all clear. MANY THANKS!!

using NUnit.Framework;
using DryIoc;

namespace DryIocTests
{
    [TestFixture]
    public class TestClass
    {
        private IAppSettings appSettings;
        [OneTimeSetUp]
        public void Setup()
        {
            //pretend we have read a json file in our mobile app
             appSettings = new AppSettings
            {
                CloudSettings = new CloudSettings {TestPropertyTwo = "Two"}
            };
        }

        [Test]
        public void ThisWorksButIsNotWhatIWant()
        {
            using (var container = new Container())
            {
                container.Register<ICloudSettings, CloudSettings>();
                container.Register<ICloudSampleViewModel, CloudSampleViewModel>();

                var vm = container.Resolve<ICloudSampleViewModel>();
                //I know that setting the property like that will work
                //but I do not want to do that .I wanted to find a way that by the time the viewModel is resolved the interface got values
                vm.CloudSettings = appSettings.CloudSettings;

                Assert.IsNotNull(vm.CloudSettings);
                Assert.IsNotNull(vm.CloudSettings.TestPropertyTwo);
            }
        }
        [Test]
        public void HowDoIMakeThisToWork()
        {
            using (var container = new Container())
            {
                container.Register<ICloudSettings, CloudSettings>();
                container.Register<ICloudSampleViewModel, CloudSampleViewModel>();

                var cloudSettings = container.Resolve<ICloudSettings>();
                cloudSettings.TestPropertyTwo = appSettings.CloudSettings.TestPropertyTwo;

                container.UseInstance(typeof(ICloudSettings));

                //by now I want that myviewmodel has the injected interface ICloudSetting populated.
                var vm = container.Resolve<ICloudSampleViewModel>();

                Assert.IsNotNull(vm.CloudSettings.TestPropertyTwo);
            }
        }
    }

    public class CloudSampleViewModel :ICloudSampleViewModel
    {
        public CloudSampleViewModel(ICloudSettings cloudSettings)
        {
            CloudSettings = cloudSettings;
        }

        public ICloudSettings CloudSettings { get; set; }
    }
    public class AppSettings : IAppSettings
    {
        public CloudSettings CloudSettings { get; set; }
    }
    public class CloudSettings: ICloudSettings{public string TestPropertyTwo { get; set; }}
    public interface IAppSettings
    {
        CloudSettings CloudSettings { get; set; }
    }

    public interface ICloudSettings{string TestPropertyTwo { get; set; }}
    public interface ICloudSampleViewModel{ICloudSettings CloudSettings { get; set; }}
}

Solution

  • Here is live working example.

    The full code is below. Search for FIX! to see the actual fixes.

    using System;
    using DryIoc;
    
    public class Program
    {
        public static void Main()
        {
            var p = new Program();
    
            p.Setup();
    
            p.ThisWorksButIsNotWhatIWant();
    
            p.HowDoIMakeThisToWork();
        }
    
        private IAppSettings appSettings;
    
        public void Setup()
        {
            //pretend we have read a json file in our mobile app
            appSettings = new AppSettings
            {
                CloudSettings = new CloudSettings {TestPropertyTwo = "Two"}
            };
        }
    
        public void ThisWorksButIsNotWhatIWant()
        {
            using (var container = new Container())
            {
                container.Register<ICloudSettings, CloudSettings>(
                    made: PropertiesAndFields.Of.Name("TestPropertyTwo", _ => appSettings.CloudSettings.TestPropertyTwo)); // FIX!
    
                container.Register<ICloudSampleViewModel, CloudSampleViewModel>();
    
                var vm = container.Resolve<ICloudSampleViewModel>();
    
                Console.WriteLine("vm.CloudSettings: " + vm.CloudSettings);
                Console.WriteLine("vm.CloudSettings.TestPropertyTwo: " + vm.CloudSettings.TestPropertyTwo);
            }
        }
    
        public void HowDoIMakeThisToWork()
        {
            using (var container = new Container())
            {
                container.Register<ICloudSettings, CloudSettings>();
                container.Register<ICloudSampleViewModel, CloudSampleViewModel>();
    
                var cloudSettings = container.Resolve<ICloudSettings>();
                cloudSettings.TestPropertyTwo = appSettings.CloudSettings.TestPropertyTwo;
    
                container.UseInstance(cloudSettings); // FIX!
    
                //by now I want that myviewmodel has the injected interface ICloudSetting populated.
                var vm = container.Resolve<ICloudSampleViewModel>();
    
                Console.WriteLine("vm.CloudSettings.TestPropertyTwo: " + vm.CloudSettings.TestPropertyTwo);
            }
        }
    }
    
    public class CloudSampleViewModel :ICloudSampleViewModel
    {
        public CloudSampleViewModel(ICloudSettings cloudSettings)
        {
            CloudSettings = cloudSettings;
        }
    
        public ICloudSettings CloudSettings { get; set; }
    }
    
    public class AppSettings : IAppSettings
    {
        public CloudSettings CloudSettings { get; set; }
    }
    
    public class CloudSettings: ICloudSettings{ public string TestPropertyTwo { get; set; }}
    public interface IAppSettings
    {
        CloudSettings CloudSettings { get; set; }
    }
    
    public interface ICloudSettings{string TestPropertyTwo { get; set; }}
    public interface ICloudSampleViewModel{ICloudSettings CloudSettings { get; set; }}