1
votes

As I'm still somewhat of a newcomer to all things DPI / C# and similar, I'm currently struggling a bit with the best way to achieve my goals.

Prism/Unity and Azure Mobile Services are working, no problems there. My question arises from being stumped on how to properly combine the two mechanics.

Basically, I have a model e.g. Group which in turn has several GroupMember. With a foreign-key-alike and some LINQ-magic I can get the Group and its members like so:

Group group = (await groupsTable.Where(g => g.Id == Id).ToListAsync()).First();
List<GroupMember> groupMembers = await groupMembersTable.Where(gm => gm.group_id == group.Id).ToListAsync();

Hereby the Group and GroupMembers instantiated from the underlying SQLite-Table (I'm using offline sync) with the data from the table queries.

The tables I get from an MobileService instance which I registered with the IUnityContainer (so I can exchange the mobile service with a mock one for unit tests).

However, what do I do if I want to register the IUnityContainer in the model (e.g. to do something like GetSiblings() or GetChildren())? Basically, I need access to the IUnityContainer inside the models but due to the way they're instantiated, the DependencyInjection gets bypassed and something like:

[Dependency]
public IUnityContainer _container { get; set; }

remains null. I've also read that it's considered bad to make the container static, so...

... also I don't think that something like:

foreach(var member in groupMembers) {
    member._container = container;
}

is the way to go. Any hints?

1
If you have container referenced directly in your model classes or busines logic, you are doing IoC wrong. A container is used to resolve or configure your dependencies in the Composition Root, it is not intended to be used directly. Think of a code that is unaware of container presence, a code that works with or without a container. Otherwise you are misusing the idea. Unfortunately, this is not what you ask about and I can't make an answer out of this comment. - Wiktor Zychla
I could also reference the MobileService I put in the container. Still doesn't change the fact that it doesn't get resolved automatically. - Rhywden

1 Answers

1
votes

You typically don't want a reference to either the dependency container (Unity) or the location where the data resides (SQLite or MobileService). Your model shouldn't be more than properties and maybe some business or validation logic.

What you're looking for is e.g. the Repository pattern (note that there are multiple ways/patterns to solve this). In short: your viewmodel will ask the repository (which will get the MobileService injected) for a 'group with members' and the repository will take care of fetching the group(s), fetching the items and add the correct items in their parent groups. Only the repository knows where to get the items from (SQLite, MobileService, ...) and how to get these.

The next step is typically to put an interface on the repository and inject that into your viewmodel. Now all dependencies will get resolved by Unity and you'll have testable units. You can see this structure in the Prism samples as well.