My question is in regard to the first "M" in MVVM, the model. I see a ton of variations on how to implement the model. Some are just POCO's with no business logic and no persistence logic, and others contain one or both.
Right now, in our application, we have a decent separation between models, views, and view-models. This is our current solution structure (its a WPF prism application):
Infrastructure
Module A
ViewModels
Views
Module B
ViewModels
Views
Models (shared amongst modules, which is why its in its own class library)
Services
DataAccess (possibly utilizing dapper-dot-net)
Shell (main WPF project)
We now need to figure out how to perform our CRUD against the database and keep our models updated. I like the idea of keeping the models pretty bare-bones and having a "Services" class library that contains our business logic and performs a unit of work pattern against our data access classes. Are there any known issues with keeping the models dumb and ignorant of business logic / data access? Is this pretty uncommon to do in MVVM?
I wonder if I'm limiting myself or making things more complex than they need to be by not placing some logic in the models, for example, loading a model from within its ctor given an argument. As a note, this will be a large application.
Our application will have to persist models to multiple databases. We're using Unity as our dependency injection container for our services. How would you recommend I tell the service which data connection to use? Ctor, per function, etc?
Kinda looking for someone who built a similar structure, and what their experiences were / recommendations are.
In my view, MVVM models just 'represent' the data and should therefore not have any logic, CRUD or otherwise embedded. You already have the Data Access Layer so it is perfectly normal to write your CRUD code there and to use DI to access this CRUD code from your models.
The "beauty" of MVVM is that it is open to interpretation so I'm sure someone else would argue that model IS the data and it can containt CRUD logic...
I have all my CRUD operations in my DAL and am yet to see the downside of that approach...
Related
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.
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
I want to know the right concept about it. If I have a MVC application with Repository Pattern, where the BL should be?
Should it be inside the Model? Model should have all the business
logic before call the unitofwork to insert or not the data into
database?
Should it be in the controller? Before call the model?
Should I have a service layer to do the business logic and decide if
I should call the Model to call the UnitOfWork to save the data?
A good explanation will help a lot too.
The short answer - it depends. If it's a fairly complex or sizable application, I like to create a service layer project with the repositories as dependencies. If it's a small application, I'll put the logic in the controller. In my opinion, if it takes more time and effort to create the service layer than it would be to create the application (i.e. one or two controllers), then it doesn't make sense to me to go that route. You also need to consider the likelihood that the application will grow. What might start small could grow into something much bigger and in that case, again, it might be more beneficial to create the separate service layer.
The third one... and then some.
Your application structure could look like this (each in different projects):
Data storage layer (e.g. SQL database)
ORM (e.g. NHibernate or Entity Framework)
Domain (including abstract repositories and entities)
Service layer (and optionally business)
MVC application (which has it's own models relating to the entities)
but there are many ways to go about this depending on the complexity and size of your application.
There is no "correct" answer to this question, it is primarily opinion-based. You can read about my opinion in the following project wiki:
https://github.com/danludwig/tripod/wiki/Why-Tripod%3F
https://github.com/danludwig/tripod/wiki/Dependency-and-Control-Inversion
https://github.com/danludwig/tripod/wiki/Tripod-101
https://github.com/danludwig/tripod/wiki/Testing,-Testing,-1-2-3
https://github.com/danludwig/tripod/wiki/Command-Query-Responsibility-Segregation-(CQRS)
Another piece of advice I would like to offer is never put any business logic in viewmodels or entities. These classes should not have methods, only properties to contain data. Separate your data from behavior. Use models for data, and other types for behavior (methods).
I will try to explain in as much detail as possible. There may be similar questions here on SO and I've gone through all of those but none of those have what I needed.
So, I'm starting out with a large scale C# MVC5 based Web Project and I want to organize everything in as much decoupled way as possible. For the database part I'm going to use Data Access ORM from Telerik (Previously known as Open Access) because I will be using MySQL for my project.
So far I have organized everything as below. I have defined solution level folders to divide the projects because I think there may be a possibility to have more projects in one layer in future.
**Solution**: td
- Business (Folder)
-- td.core (Project) (Contains Services and ViewModels)
-- td.interfaces (Project)
- Data (Folder)
-- td.data (Project) (Contains Database Models i.e. Telerik, Repository, Context Factory and Unit of Work class)
- Presentation (Folder)
-- td.ui (Project) (MVC5 Project, also Implemented IoC here)
- Shared (Folder)
-- td.common (Project)
Generally, when you bind models in your MVC project, if you have just one project in your solution, it works pretty easily without an issue.
i.e. in a MVC Controller
var obj = new TempClass();
return View(obj.getAllUsers());
and then in the corresponding view you use this at the top
#model (model type here)
When I separate all these layers in their own projects as mentioned above. The data layer would be the one directly communicating with the database hence I will generate the Telerik Data Access rlinq schema in my Data node where it will also generate the classes for the tables in my database (Default config)
Now, from the setup above, from the controller I'm supposed to call the Business layer to fetch the data and which will communicate with the Data node.
The question is that in the controller and in the view I will need the data types / references of the model I'm binding to. So, should I keep my automatically generated classes still in the Data node or can I move ONLY the generated classes to the Shared Node and then use those for the binding in the Controller/View? Which one is going to be a good practice? as I don't want to reference the Data nodes directly in the controller otherwise there is no point in separating everything like above.
Another quick question. I would be integrating so many third party APIs via REST/SOAP. In which layer should these best fit?
If anyone has any other Architectural suggestion or something that I'm missing here, please do suggest.
Thanks in advance everyone.
UPDATE!!!
Please see my updated architecture above.
Here's what I did so far.
I have added Repositories, Services and IoC.
In my Global.asax, I'm initializing the IoC which configures the Services etc for me.
My controller has an overloaded constructor now having the service from the business layer as the parameter.
Controller calls the service to get the data and the service calls the repository for it.
I have followed the generic repository path instead of creating repositories manually for each type
For 3rd party APIs, I will use the data layer and business later won't know where the data came from. It just needs to ask what it needs.
All this was made easier with the help of a dedicated Interfaces project which is being referenced from both the Business and Data layers when needed. Because as both want to implement abc interface I cannot declare it in either Business or Data layer since there would be circular referencing then which prevents me to reference both (Business/Data) projects to each other.
So, with the help of above changes, I can easily do what I want now and Everything is working perfectly as I want. Now the last question I have is
Is there any flaw in this architecture?
For a domain-centric architecture where it's easy to add another type of UI or change persistence technology and where business classes are easily testable in isolation, here's what I'd do :
Business layer with no dependencies. Defines business types and operations.
Data layer with data access objects/repositories that map from database to business types. You can also put your third party API accessors and adapters here. Depends on Business layer where repository interfaces are declared.
No Shared layer. Business types are the basic "currency" that flows through your system.
UI layer depending on the data access interfaces declared in the Business, but not on the Data layer. To decouple UI further, you can introduce an additional UI-agnostic Application layer.
You can read more about this at Onion Architecture or Hexagonal Architecture.
As it is, your architecture is pretty much data-driven (or Telerik Data driven) since the business and UI layers are tightly coupled to the Telerik schema. There's nothing wrong with that, but as I said in my comment, it enables other things such as quick development from an existing database schema, over full domain decoupling, framework agnosticism and testability.
Whether your Telerik generated model lives in the Data or Shared module makes little difference in that scenario IMO. It is still the reference model throughout your application and your controllers will be coupled to it anyway. The only thing I would advise against is moving the generated files manually - if it can be automated all the way, definitely do it or don't move the files at all.
I'm nether an expert for your special technologies, nor would I regard this as the ultimate answer, but I give you some hint's of the possibilities you may have (depending on your technologies):
Business should have exclusive access to data
Currently I don't really get, why your controller and view need access to any data-base related stuff at all? Shouldn't your business layer handle all of that and hide it from controller and view? But let's assume it's necessary for some reason.
Ways to split the data layer
You shouldn't move generated classes manually. You could change your generation-settings, to generate them elsewhere partially. But manually cherry-picking and moving them, results in an architecture which is hard to maintain.
The cleaner solution would be, if you can change the visibility of your classes. Can you generate classes with project or folder visibility instead? Or can you only export defined packages or classes in the project settings?
A workaround which requires more maintenance is the local extension. You could create new classes in your shared folder, which derive from the data layer classes.
Stucturing external APIs
Give them one or more own projects, so they are easier to change later. I know approaches where you have one main folder for each API. This makes each of them easy to change, but clutters your workspace. The important project will only be 4 out of 1000 projects. I normally prefer one folder containing all APIs. Thus the APIs are slightly harder to change, but your workspace stays clean. Your decision depends on two facts: how often do you change, add, remove or just study the APIs. And does your IDE provide a way to "hide" folders/projects from your workspace.
Hope this helps a little :)
I'm trying to structure my WPF MVVM application according to best practises. I have to start with a lot of existing code so don't have the option of resolving all structural flaws straight away. I like the following solution structure.
http://www.paulspatterson.com/technology/dot-net-development/mvvm-and-wpf-for-vb-net-series-2-part-1-again/
This separates the solution into the following projects; BusinessLogic, BusinessObjects, Infrastructure (Common reusable utilities), WPF Shell and Modules (application components to be injected using an IOC container).
I understand that the business object represents the human world entity whereas the business logic is the implementation details as discussed in this question.
What are Business Objects and what is Business Logic?
Therefore using MVVM does the business object just become a dumb container that doesn't actually do anything other than wait to have its properties changed by external business logic? I don't see how you decouple the business object from the business logic to the point of being able to have them in separate assemblies.
Take the following hugely simplified code:
public class Chart
{
private SizeChart _activeChartSize = new SizeChart();
public void Draw() {
// Size the chart object
_activeChartSize.Size(this);
// Do other draw related things
}
}
public class SizeChart
{
public void Size(Chart chartToSize) {
// Manipulate the chart object size
}
}
In the context of the MVVM solution structure described above (to my mind at least) the SizeChart class would be business logic and the Chart class would be a business object but placing them in different projects would be a circular dependency. Is the SizeChart class business logic or a business object and where in the solution structure should the SizeChart class reside if I adopt this proposed MVVM solution structure?
Apologies if this is an incredibly obvious and simple question to some people but it's difficult when you can't start with a clean slate to know how to best start transitioning poorly structured code to well structured code.
http://en.wikipedia.org/wiki/Business_object
Business Object: A type of an intelligible entity being an actor inside the business layer in an n-layered architecture of object-oriented computer programs.
Whereas a program may implement classes, which typically end in objects managing or executing behaviors, a business object usually does nothing itself but holds a set of instance variables or properties, also known as attributes, and associations with other business objects, weaving a map of objects representing the business relationships.
http://en.wikipedia.org/wiki/Business_logic_layer
Business Logic Layer : A business logic layer (BLL), also known as the domain layer, is a software engineering practice of compartmentalizing.
Within a BLL objects can further be partitioned into business processes (business activities) and business entities. Business process objects typically implement the controller pattern, i.e. they contain no data elements but have methods that orchestrate interaction among business entities.
So basically a business object models an entity (usually a real world object such as Employee or Account) whereas business logic facilitates the interaction between business objects and between other application layers.
I think the most appropriate answer was given by Daniel Hilgarth. His answer was don't separate the business logic from its objects, because this leads to an anemic domain model.
While I think the following WPF MVVM solution structure proposed by Paul S Patterson is a good one I don't think it's appropriate for everyone.
http://www.paulspatterson.com/technology/dot-net-development/mvvm-and-wpf-for-vb-net-series-2-part-1-again/
The creation of distinct Business Logic and Business Object projects probably works best if your business objects are Data Transfer Objects (DTOs) e.g. Linq to SQL rather than a more complex object such as a composite that may have tighter coupling to the business logic.
Business object is a rather amorphous term - is it a DTO, a POCO, or a mix of that with some business logic thrown in?
To me, I would consider something different - Chart and SizeChart are both controls rather than "business objects" or "business logic". It's not the fact that they have UI sounding function names in them, but that they are actually doing UI or rendering related work (sizing and drawing). The collection of data that these work with would be separate and would be assigned to the controls before invoking Size or Draw.
Note that this answer is agnostic of MVVM as it is a bit of a red herring - your question is more closely related to general n-tier design in which you also incorporate MVVM.
I ran into something similar on a project recently.
We have a web app that allows an administrator to create groups. One of the rules that was required was that you couldn't create two groups of the same name. What we ended up doing was creating a very basic object, a Group, and then creating a service called GroupService. GroupService does the rule checking so that when a user calls GroupService.Save(Group), the service goes out and checks for prior groups with the name. If the name is found, an error is given back to the user and the save doesn't occur.
In our case, the hierarchy is Controller has Services, Services have Repositories, and Repositories finally commit to the database. Running throughout each of these abstractions is the model, Group. But our model isn't just a 'dumb' object. It does contain the validation logic on the data fields themselves and has aggregate properties to simplify databinding.
Expanding this to the MVVM conecept, I would think the View Model would have the service that contains the business logic and a model that was to be incorporated into the View. Obviously the View would be bound to the ViewModel, but the ViewModel would have some instance of the Model object to bind to.