uFrame MVVM and Separation of Concerns

Some of you that used to work (or work) with Unity3D might be tempted to use library called uFrame MVVM to get things seperated in proper, documented way.
As I’m currently working on a project that uses uFrame MVVM, I’d like to add few words of how and where I find uFrame MVVM actually not meeting one from many SOLID rules, that is Single Responsibility Principle and it’s a-like principle: Separation of Concerns (SoC).

About uFrame MVVM

Few words about uFrame MVVM first.
UFrame has been developed by Invert Game Studios to mimic MVVM pattern behaviour known to C# developers from WPF or ASP.NET frameworks.

Direct link to uFrame is here:

https://invertgamestudios.com/mvvm/overview

Although it’s marketed as ‘MVVM’ and it does have Views that bind to ViewModels, it resembles me more how ASP.NET MVC work with MVVM client-side, JS-based frontends.
Actually it lacks the ‘M’ (Model) part. ViewModels are used from start in a way generally models are. Logic that sometimes grows too much in WPF MVVM inside ViewModels lays in Controllers here.
I’m really delighted that finally that big-blob-VM are gone from my code and instead a true Controller taken from MVC pattern takes the responsibility.
Current way how uFrame works would be probably easier to understand with diagram I’ve prepared:

uframe mvvm seperation of concerns

Straight to the problem

Here comes the real problem though: access to instantiating views from code is accessible from Views only(!?).
I can imagine that it’s due to the fact that they’re the only ones deriving from MonoBehaviour but it strictly implies that we should use them for non-UI logic, that is validation and modification of data that should drive instantiation of Views (for ex. ModelCollection that instantiates new View based on ViewModel added to it and notified OnPropertyChanged).
Although I can understand reasons why it was designed that way (Unity3D limitations probably), I can hardly accept way of design it promotes.

My solution

My idea is to implement widely known (also from everyday life) pattern known as Producer/Consumer pattern.
We can subscribe with great reactive-programming library UniRx tool that is already used in uFrame, that is Subscribe and IObservable to ModelCollection, then we can do any business logic and validation in Controller, that is in way it’s mean to be designed.
Our next step will be pushing newly added item do InitializationContainer if it meets our business requirements/is valid etc. Then we will need an Initializer (that will be View in uFrame sense but will behave as normal MonoBehaviour for us) where T is type of ViewModel/View that we’re going to subscribe for to InitializationContainer and then consume it.
Consuming of notified View to initialize should end up in deleting the item from initialization queue in container.
We need to remember that our notification should contain both View and ViewModel, so that Initializer knows what View with what ViewModel it should instantiate.
For better understanding of an idea, here’s a next diagram:

uframe mvvm container initialization

Hope it helps anyone struggling with inconsistend seperation of concerns in uFrame MVVM! :)

Leave a Reply

Your email address will not be published. Required fields are marked *