C#' MVVM Observable Proxies aka Android LiveData? - c#

I am developing a C# wpf mvvm application in which the Model Data is represented by hierarchies and my ViewModels have to observe Parts of the hierachies in between. I would like to come up with a design that makes the application easier to maintain when the structural hierarchies of the Model change.
Example:
The Model has a hierarchy A->B->C->D. The ViewModel wants to get change notifications of D and B. At some point another ViewModel sets A to a completly new value and all other observing ViewModels have to be notified that their respetive D and B are no longer valid.
My design idea so far:
I flatten the hierachy of the models by replacing the direct reference with an unique Identifier like GUID. When a ViewModels wants to get an instance of D it actually has to ask a Repository to get an observable Proxy of D. When a write to A occurs, the observable Proxy gets notified about it and therefore the ViewModel also gets notified. The life cycle of the obervable proxy is bound to the ViewModel thats using it, e.g. the ViewModel decides when the observable proxy will be disposed.
Is there maybe already a pattern that solves this problem in C# MVVM? I saw that Android Jetpack introduced LiveData and it looks very similar to what i am trying to do.

TLDR: Anemic Domain Model, entities that reference other entities with unique keys and messagebus is the way to go.
After studying the problem I came up with a few proven solutions.
According to DDD (Domain Driven Design): Its OK to reference other aggregates by Index but not object reference. Aggregates should only be accessed via the aggregate root and encapsulate logic and child entities inside the aggregate root. This is OOP and you end up with easy to use objects that overtime become fat filled with methods and fields because, well just look at the WPF framework UserControl when you enter 'this.' and an accordeon of fields, methods and events reveals to you. One could argue that you can use inheritance and move methods out with mediators to reduce your 5kloc OOP source files, but mediator is just procedural style programming in disguise which leads me to...
The Anemic Domain Model. Entities are just data containers without behavior (methods) and only have fields that are simple or reference other entities by keys. On top of the dumb entities are the 'services' which are just stateless collections of methods that run on the dumb entities. Every write operation by a service will trigger some kind of messaging, either a message bus or other.
The anemic domain model pattern is very popular in games industry right now, but they call it 'Data oriented Design' or DOD. DOD boils down to lots of dumb data component objects where some methods run on them with the goal to achieve easy parallelism and cache coherence. In my opinion thats just old school procedural C programming with handles and it makes sense for high performance applications.

Related

Event Sourcing and Clean Architecture - does domain model need to handle events?

I'm still learning clean architecture and now I'm trying to implement event sourcing in project.
I have 2 projects, one that hold commands and events and one where is domain model.
By definition of clean architecture domain model is center of everything. Everytthing references him.
But, all examples that I found shows that domain model have Apply methods for each event.
Do I need to do this in domain model? Or is some other way?
In some point in code I need to reconstruct domain model from events something like this:
public void Load(events){
foreach(var event in events)
{
Apply(event);
}}
This should be in domain model class, like Apply method.
Apply method changes internal state of domain model.
all examples that I found shows that domain model have Apply methods for each event.
Do I need to do this in domain model?
You don't "have to" do that, but it is a likely outcome in a Kingdom of Nouns design. Since much of the early development of domain driven design (Java) and event sourcing (C#) were taking place in the Kingdom of Nouns, the examples tend to share these patterns.
With the Apply pattern, you are seeing the result of two different ideas.
One, the idea that all event sourced models have the same underlying data structure (Truth is the history of events), so we should be using a single common, general purpose implementation for all of them.
Two, that the information we cache within the data model (aka the model object's "properties") should look "the same" whether we are looking at the original object that processed the command or if we are instead looking at a copy of that model loaded from the history.
Thus, a pattern emerged that models tend to "inherit" from some base class that owns an event history and an api for coordinating changes to both the history and the models own internal cache, and that command handlers on the model work by first calculating what changes (events) should happen, then applying those changes using the same code paths that would be used when reloading the event history.

Converting WPF application to follow DDD

I am trying my hands at DDD for the first time, and got stuck in the middle.
Current Design:
Our current design, not elegant but simple and works. Views bind to ViewModels, and ViewModels have reference to the ServiceClients. When user requests something on the View, it changes the state of ViewModels, and ViewModels in-turn requests ServiceClients. ServiceClients can respond to the requests either synchronously, or asynchronously.
Pros: Very simple design, and works.
Cons:
Tightly coupled to everything, everyone needs reference to everything to get things done.
Violating SOLID largely.
God objects every-where
Not testable at all!
DDD:
I decided to take refuge in DDD, to get rid of all the cons mentioned above. The idea was to carve-out Models from ViewModels, and break dependency between ViewModels and ServiceClients. So far so good.
The major issue I am facing here is the project is becoming highly event driven now. I have to fire a lot of events to get a simple operation executed.
For instance: If ViewModel has a request for ServiceClients
ViewModel will invoke an operation on the Model object,
Model fires an event, which ServiceClients handle.
ServiceClients will invoke an operation on Model to send response
Model will fire an event, which is handled by ViewModel to receive the response
The question is:
1. Is the architecture laid out correctly?
2. Is eventing necessary to get simple things done?
Thank you for your time.
Without knowing sufficient details about the actual use-case, I would venture and say you are facing this problem because you are only applying the tactical patterns of DDD without spending enough time on the strategic side.
Let me explain.
Even when there is an existing codebase like you do, you want to start thinking about high-level boundaries in the system, key actors, their behavior, and interactions between key actors. You should identify the different bounded contexts in your domain and the connections between them.
More importantly, you should try to capture the domain functionality as-it-is in the codebase. By that, I mean representing concepts in the application to mirror what a domain expert would say.
If you take your existing codebase and directly try to apply the domain modeling concepts of Aggregates/Value Objects/Domain Events etc., what often results is spaghetti code where everybody references everybody else, and dependencies are left unchecked. This interdependency leads to a situation where an update in one part of the system triggers an application-wide change and needs the extensive use of Domain Events.
Further reading:
The Two Sides of Domain-Driven Design (DDD)
DDD Strategic Patterns: How To Define Bounded Contexts
Vladimir Khorikov's Pluralsight Course (Uses the same code structure as yours)

WPF MVVM Model how to get data

Recently, I'm learning MVVM design pattern!
In my way, I write the database function in the model, and let the viewmodel to call the database function in the model, then the viewmodel get database data and set to the viewmodel notfiypropertychanged. This is my way that I currently use!
There are some question confused me about model,
I read many article that told me model just a contain data and not more business logic, and here is my question, if model just a data container and I need to let my viewmodel to call the database then get data and set to the model, I think this way is very strange and the viewmodel code is make heavy in it. Is anybody have another method to do it? Thank you!
The Model:
"model just a contain data and not more business logic"
A model is a class which describe an entity within your domain logic. What is a domain? Starbuck's domain is coffee beverages and employees (among others), Ford's domain is cars, assembly lines, and employees. NYTimes's domain is articles, issues, supply routes, subscribers, etc, etc.
A model contains data AND logic. You can have multiple models to describe your domain.
You can place your data calls in your model, but it's more common to have helper classes, data access layers (DAL), keeping all your database calls in one place, and not spread them around.
The ViewModel:
The viewmodel sits between your domain model and your view. It's a class which expose properties of the model and represents the state of the view. The viewmodel may only exposes a subset of all the properties in the model that the UI needs to display, but it could also add properties of its own, for example; is the user in edit mode? have changes been made that needs saving? etc. The selling point with MVVM is that the UI binds to these properties on the viewmodel which is a mechanism to keep the UI up to date with changes, and this extra layer of abstraction conveniently decouples the view to any logic in your model making it more robust for code changes in either direction and testable. There's more to say on this topic, but I'll leave it to you to read on up it.
There are many good resources and info on the MVVM pattern; from blogs Model-View-ViewModel (MVVM) Explained, to Microsoft The MVVM Pattern and here on SO.
If you prefer videos, Pluralsight have good video tutorials on the MVVM pattern
Practical MVVM and WPF MVVM In Depths. They have a free 30-day trial.
"just a data container"
Such classes that only hold data to be passed around are often called Data Transfer Objects (DTO). It's common to keep them small and return collections of these from fetch database data method calls.
I've done some research in this and also found it quite confusing. First thing I like to point out is that code-patterns are abstract. Meaning that you have loads of different way to implement it / tweak it.
What most people have told me is that in "real-life" applications you usually have layers of services.
One of these services is where you get data from a database.
The Model job (in my opinion) is to give the developer knowledge about the database data and structure. One Model to one database-tabel.
It also helps in checking if the data is correct (Format checking, Type of data and so on) before sending it to the DB.
There isn't a clear answer on how to use model. I've seen loads of different implementations, and they all have been implemented for specific tasks.
Yes it might come out that some ViewModels become heavy-loaded with code and functions to perform, but then it might not be because of the code-pattern. It can be because of poor structure in code. At my work right now I've found a ViewModel that contained over 3000 lines of code (Which is WAY to much). This could easily be seperated into atleast 3 different ViewModels and Views, but as I said, poor code structure causes problem.
One thing I recommend for you to read up on is
IoC - Inversion of Control
DoP - Dependency inversion principle
DI - Dependency Injection
Hope this helps in someway explaining your question.
I read many article that told me model just a contain data and not more business logic
A model may be represented by a service, a database access layer or a business layer so there is nothing wrong with your current approach. The business logic does belong to the model.
But sometimes people tend to refer to a "child" type as a model. For example, if your view model exposes a List<Item> property, the Item class may considered to be a model. Perhaps your confusion comes from this.
This kind of classes (Item) typically implement the INotifyPropertyChanged interface to provide change notifications and are effectively rather just "nested" view models that don't contain any business logic though.
Hope that makes sense.

MVVM - Patterns and Practicality

I've been using MVVM for a while now with WPF. And i've learnt a lot over the course of development (going from never using it, to having a couple of applications developed in it)
However, recently I had some comments directed at the code which made me wonder if i'm doing things the right way. My current setup works (roughly) like this:
Model - Responsible for storing the data, data validation using
IDataErrorInfo and dirty tracking
ViewModel - Responsible for getting the data (from a repository like
pattern) and formatting it for a view's consumption (things like
filtering, ordering) also responsible for command handling from the
view (save, load, filter changes etc)
View - The usual UI stuff
Now it was mentioned to me that i should NEVER have business logic inside the model, and that the model should be as thin as possible, the viewmodel should be responsible for handling things such as data validation and dirty tracking.
I've seen comments and criticism on both sides of this, with people against and for putting logic in the model, What i have yet to see is any actual reasons for these sweeping statements. So id love to know if there is an actual reason i should be refactoring my setup.
Also, given that i do move the logic to the viewmodel, I can see the need for having multiple viewmodels where i currently have a single, for example:
Person - Model
PersonViewModel - Handles the dirty tracking, data validation etc
PersonsViewModel - Handles getting a collection of PersonViewModels,
filtering etc
PersonsView - The UI
This seems a little redundant, but perhaps i'm misunderstanding something. What I'm really looking for is some actual reasons for doing this one way or another, or if this is another argument like the use of code-behind in MVVM (pure opinion with little reasons etc)
High level description of MVVM:
View: User Interface
Model: Business logic and data (e.g Domain Model+Repositories, or Transaction Script+POCO entities, etc)
ViewModel: Data exposted to view in such form, that is easily consumable from view. Wikipedia's definition says: The view model is an abstraction of the view that exposes public properties and commands.
I like the Practical MVVM Manifesto (archived version) principes: Simplicity, Blendability, Designability, Testability.
This is very high level and abstract description and that's why you may find a lot of variations of MVVM. Whatever mvvm style you choose, keep in mind the responsibilities and principles and you should be ok. Try to avoid complexity. MVVM is not a silverbullet and you cannot cover all scenarios with single design pattern. One mvvm implementation may be suitable for one application but not for another. I, for example, build my mvvm architecture from scratch for each new project to ensure the best fit
When is comes to responsibilities:
Take validation as an example:
validation logic that password and repeat password inputs should be equal is clearly presentation logic and should be present in viewmodel. On the other side, there may be business rule, that password must contain at least one special character. This logic should reside in Model, however you may expose it in viewmodel to be easily consumable from view. It's a business logic, but you may need to present it somehow.
if you have application that only uses webservice to retrieve and store then your model will be probably just the data access components.
Here is couple of resources:
Wikipedia: https://en.wikipedia.org/wiki/Model_View_ViewModel.
MVVM is variation of Martin Fowler's MVP pattern, you may find it useful as well: http://martinfowler.com/eaaDev/PresentationModel.html
MSDN (Pattern and practices): https://msdn.microsoft.com/en-us/library/hh848246.aspx
I like to think of the Model layer as anything that has nothing to do with how the app is hosted (i.e. independent of WPF). It is one or more dlls that represent the business domain and the operations that need to be performed in it. If it would make sense to take theses same dlls and use them in a web application, windows service e.t.c then it is usually a sign that the split between Model and ViewModel is appropriate.
There's no simple answer to your question. The simplest answer is that the model and view model should contain the code that you should unit test. The separation between model and view model is a little less distinct. I like to keep the model as simple as possible and limit it to whatever is exchanged with the server tier. The view model should encapsulate the model, and provide any addition functionality (both business logic and abstract presentation logic) so that you can keep the presentation layer as simple as possible (declarative, in the case of WPF XAML).
I see it this way:
Model - Object that can be passed around. A Common type between different layers for communication.
ViewModel - Specifically created for Views. This should contain UI logic, for example, Data Annotations etc will go here. You might also call your web service methods here (assuming your actual business logic sits in a facade layer, or your database logic sits in a different layer/project) to populate the Views, dropdowns etc. You might end up with multiples of these per view, depending on your design.
View - UI Only.
I am not afraid to put external calls in the ViewModel

In a layered architecture using Entity Framework, should I return POCO classes from the BLL? (Architecture guidance needed)

I've been reading too much probably and am suffering from some information overload. So I would appreciate some explicit guidance.
From what I've gathered, I can use VS2010's T4 template thingy to generate POCO classes that aren't tied directly to the EF. I would place these in their own project while my DAL would have an ObjectContext-derived class, right?
Once I have these classes, is it acceptable practice to use them in the UI layer? That is, say one of the generated classes is BookInfo that holds stuff about books for a public library (Title, edition, pages, summary etc.).
My BLL would contain a class BooksBLL for example like so:
public class BooksBLL
{
ObjectContext _context;
public void AddBook(BookInfo book) { ... }
public void DeleteBook(int bookID) { ... }
public void UpdateBook(int bookID, BookInfo newBook) { ... }
//Advanced search taking possibly all fields into consideration
public List<BookInfo> ResolveSearch(Func<BookInfo, bool> filter) { ... }
//etc...
}
So, my ViewModels in my MVVM UI app will be communicating with the above BLL class and exchanging BookInfo instances. Is that okay?
Furthermore, MVVM posts on the Web suggest implementing IDataErrorInfo for validation purposes. Is it okay if I implement said interface on the generated POCO class? I see from samples that those generated POCO classes contain all virtual properties and stuf and I hope adding my own logic would be okay?
If it makes any difference, at present, my app does not use WCF (or any networking stuff).
Also, if you see something terribly wrong with the way I'm trying to build my BLL, please feel free to offer help in that area too.
Update (Additional info as requested):
I'm trying to create a library automation application. It is not network based at present.
I am thinking about having layers as follows:
A project consisting of generated POCO classes (BookInfo, Author, Member, Publisher, Contact etc.)
A project with the ObjectContext-derived class (DAL?)
A Business Logic Layer with classes like the one I mentioned above (BooksBLL, AuthorsBLL etc)
A WPF UI layer using the MVVM pattern. (Hence my sub-question about IDataErrorInfo implementation).
So I'm wondering about stuff like using an instance of BooksBLL in a ViewModel class, calling ResolveSearch() on it to obtain a List<BookInfo> and presenting it... that is, using the POCO classes everywhere.
Or should I have additional classes that mirror the POCO classes exposed from my BLL?
If any more detail is needed, please ask.
What you're doing is basically the Repository pattern, for which Entity Framework and POCO are a great fit.
So, my ViewModels in my MVVM UI app will be communicating with the above BLL class and exchanging BookInfo instances. Is that okay?
That's exactly what POCO objects are for; there's no difference between the classes that are generated and how you would write them by hand. It's your ObjectContext that encapsulates all the logic around persisting any changes back to the database, and that's not directly exposed to your UI.
I'm not personally familiar with IDataErrorInfo but if right now your entities will only be used in this single app, I don't see any reason not to put it directly in the generated classes. Adding it to the T4 template would be ideal if that's possible, it would save you having to code it by hand for every class if the error messages follow any logical pattern.
Also, if you see something terribly wrong with the way I'm trying to build my BLL, please feel free to offer help in that area too.
This isn't terribly wrong by any means, but if you plan to write unit tests against your BLL (which I would recommend), you will want to change your ObjectContext member to IObjectContext. That way you can substitute any class implementing the IObjectContext interface at runtime (such as your actual ObjectContext), which will allow you to do testing against an in-memory (i.e. mocked) context and not have to hit the database.
Similarly, think about replacing your List<BookInfo> with an interface of some kind such as IList<BookInfo> or IBindingList<BookInfo> or the lowest common denominator IEnumerable<BookInfo>. That way you're not tied directly to the specific class List<T> and if your needs change over time, which tends to happen, it will reduce the refactoring necessary to replace your List<BookInfo> with something else, assuming whatever you're replacing it with implements the interface you've chosen.
You don't need to do anything in particular... as Mark said, there is no "right" answer. However, if your application is simple enough that you would simply be duplicating your classes (e.g. BookInfoUI & BookInfoBLL), then I'd recommend just using the business classes. The extra layer wouldn't serve a purpose, and so it shouldn't exist. Eric Evans in DDD even recommends putting all your logic in the UI layer if you app is simple and has very little business logic.
To make the distinction, the application layer should have classes that model what happens within the application, and the domain layer should have classes that model what happens in the domain. For example, if you have a search page, your UI layer might retrieve a list of BookSearchResult objects from a BookSearchService in the application layer, which would use the domain to pull a list of BookInfo.
Answers to your questions may depend on the size and complexity of your application. So I am afraid there will be valid arguments to answer your questions with Yes and No as well.
Personally I will answer your two main questions both with Yes:
Is it acceptable practice to use POCO (Domain) classes in the UI layer?
I guess with "UI layer" you don't actually mean the View part of the MVVM pattern but the ViewModels. (Most MVVM specialists would argue against letting a View directly reference the Model at all, I believe.)
It is not unusual to wrap a POCO from your Domain project as a property into a ViewModel and to bind this wrapped POCO directly to the View. The big Pro is: It's easy. You don't need additional ViewModel classes or replicated properties in a ViewModel and then copy those properties between the objects.
However, if you are using WPF you must take into account that the binding engine will directly write into your POCO properties if you bind them to a View. This might not always be what you want, especially if you are working with attached and change-tracked entities in a WPF form. You have to think about cancellation scenarios or how you restore properties after a cancellation which have been changed by the binding engine.
In my current project I am working with detached entities: I load the POCO from the data layer, detach it from context, dispose the context and then work with that copy in the ViewModel and bind it to the View. Updating in the data layer happens by creating a new context, loading the original entity from the DB by ID and then updating the properties from the changed POCO which was bound to the View. So the problem of unwished changes of an attached entity disappears with this approach. But there are also downsides to work with detached entites (updating is more complex for instance).
Is it okay if I implement the IDataErrorInfo interface on the generated POCO class?
If you bind your POCO entities to a View (through a wrapping ViewModel) it is not only OK but you even must implement IDataErrorInfo on the POCO class if you want to leverage the built-in property validation of the WPF binding engine. Although this interface is mainly used together with UI technologies it is part of System.ComponentModel namespace and therefore not directly tied to any UI namespaces. Basically IDataErrorInfo is only a simple contract which supports reporting of the object's state which also might be useful outside of a UI context.
The same is true for the INotifyPropertyChanged interface which you also would need to implement on your POCO classes if you bind them directly to a View.
I often see opinions which would disagree with me for several architectural reasons. But none of those opinions argue that another approach is easier. If you strictly would want to avoid to have POCO model classes in your ViewModel layer, you need to add another mapping layer with additional complexity and programming and maintenance effort. So I would vote: Keep it simple as long as you do not have a convincing reason and clear benefit to make your architecture more complex.

Categories