DPI / IoC combined with other frameworks



  • Okay, so the situation is the following:

    I'm using AzureMobileServices as a data provider in my app. As I want to do some unit tests on the models consuming the data, I registered an instance of the service on the IUnityContainer for my app. The unit test suite gets a different (mock) instance of the service. So far so good.

    I can pull data from the models and everything is fine.

    Now I want some of my models to be interconnected. For example, hierarchical, tree-style. Thus the models in question should get something like GetChildren() or GetSiblings() or GetParent() for convenience.

    Here's the thing, though. For that to work, the model would need to know about the service. So, normally, I'd plonk something like this into the model:

    public class Example {
        private IMobileService _service;
        Example(IMobileService service) {
            _service = service;
        }
    }
    

    and a later var _example = Container.resolve<Example>(); would get me an Example instance with the needed service reference.

    However, with the MobileService I'm getting the instances more like this:

    List<Example> exampleList = await exampleTable.CreateQuery().ToListAsync();
    

    Here every example instance would have its service reference at null. Now for the big question: How do I work around this?



  • What I would do:

    public class Example
    {
         private IMobileService _service;
    
         public IMobileSerivce MobileService 
         {
              set 
              { 
                   if(_service == null)
                   {
                        _service = value;
                   }
              }
    
         }
         //Other stuffs  here
    }
    
    
    
    var mobileService = Container.resolve<IMobileService>();
    
    foreach(var example in exampleList)
    {
    example.MobileService = mobileService;
    }
    

    Allow property injection if the backing field is null. The constructor injection can stay as-is.



  • That's what I already did. But it feels wrong somehow :)


  • BINNED

    @Rhywden said:

    it feels wrong

    Use more lube


  • ♿ (Parody)

    This is one of the convenient use cases for an ORM. It handles that for you. And yes, it always feels wrong to inject stuff like that.



  • @Rhywden said:

    That's what I already did. But it feels wrong somehow

    If you are interacting directly with the service object to locate your service, you are breaking IoC/DI. What you are then doing is "Service Locator", which is considered an anti-pattern nowadays.

    I'm not up on azure api's but could you maybe inject _example into your app, via property or constructor?



  • I opted for creating another layer between the Models and the ViewModel which basically only aggregates the data and does the stuff an ORM would normally do. Thus the models only handle the raw data and validation and this data repository handles the calculations.

    That actually has the advantage of being persistent so that the data has to be gathered only once and not every time the ViewModel changes to another page. Granted, the data then lives in memory - but as I'm dealing with data amounts even a Amiga 500 could have handled, that should not pose much of a problem.


Log in to reply