I'm creating an application using MVP: Passive View and EF (model first). As of know, I have a presenter getting data directly from the DataContext created through EF. It looks something like this:
private void UpdateOrderTableControl()
{
IList<Order> orders = dataContext.Orders.ToList();
IList<OrderViewModel> viewOrders = new List<OrderViewModel>();
foreach (var o in orders)
{
viewOrders.Add(new OrderViewModel()
{
OrderId = o.Id,
CustomerId = o.CustomerId,
LastName = o.Address.LastName,
FirstName = o.Address.FirstName,
Company = o.Address.Company,
Weight = o.Weight,
Sum = o.Sum,
Date = o.Date
});
}
view.GetOrderDataGridView().DataSource = viewOrders;
}
So the presenter gets a list of all orders, creates a list of order view models (combining data from different tables, i.e address above) and then sends the view model list to the view.
It's pretty much the same thing the other way around, when retrieving data from the view in order to edit or add to the db:
private void SaveOrder()
{
GetOrderDataFromView();
if (isNewOrder)
{
dataContext.Orders.Add(selectedOrder);
}
else
{
dataContext.Entry(selectedOrder).State = EntityState.Modified;
}
dataContext.SaveChanges();
isSaved = true;
UpdateOrderTableControl();
}
1) Can EF (the entities created through EF, the DataContext etc) be considered as the DAL? Should it be in a project of its own?
2) I guess the presenter should not have access to the DataContext like that, but rather to another layer in between the two, right? Would that be a service layer, a business layer or both?
3) Is what I refer to as a view model in fact a view model or is it something else? I just want to get my terminology right.
EDIT:
4) I read some suggestions about adding business logic to the entities generated by EF, but that doesn't sound quite right to me. Should I create business objects in a separate business layer on top of EF? Meaning I would have Order (generated by EF), OrderBO (the business object) and OrderViewModel (the order to be displayed). I would have to do more mapping, since I'd add another layer, but it would make the presenter lighter.
Thanks in advance!
Nice questions!
Well, the answer to all of them depeneds on what you plan to do. The first you have to do is to evaluate if the effort needed to implement each pattern is worth the pain.
1)Are you going to switch between different implementations of forms and/or have massive unit tests for the UI alone? Then yes passive view seems a good idea.
2)Is it not so much pain to have a litle code inside the forms? Then MVP supervising controller can be faster to implement.
3)Can most of the logic of your program be inside bussiness layer? After you have all the logic inside BL, how much logic is GUI specific? If it is not that much then code inside the forms with no GUI patterns is the way to go.
About the questions:
1) Yes, EF can be considered a DAL, and doesn't hurt to be in a different project. Since you are into patterns, a usefull pattern here is Repository and Unit of Work Pattern that abstracts EF and lets you unit test the BL. (test without accessing an actual database, with a fake DAL implementation)
2) Depends. EF objects can be considered Data Transfer Objects since they are POCO. DTOs are visible in all layers. Another strategy is to have layer specific objects, mainly in the scenario of a tiered application (each layer in different machine).
If not forced to do otherwise, I would have EF objects visible to all layers but the DataContext itself visible only to BL, not GUI layer. This means that queries and transactions are done in BL but GUI can get the results in the same format.
3) If you follow the above advice, this rather bad object copying isn't needed.
4) This strategy you refer to is the Domain Model (google for more), in which you put logic inside the domain objects, that can also access the database. Again if you follow the advice in 2), this doesn't bother you.
Before getting frustrated around patterns and their correct implementations though, really focus on your needs! The goals are fast delivery and easy maintainance. Too much abstraction can hurt both!
Regarding the question #2, it will be better to differentiate and make some abstractions on Data Access Layer. If you continue keep it inside Presenters, that means your client will ask database each time, load some data and then make some calculations.
If you are working on Client-Server application, it will be better to not mix-up the server logic and client logic. Presenters are definitely on client side, DAL on server-side. You can connect client to server with web services (ex. asmx, wcf).
I see at least three huge reasons to do this:
Ability to write simple unit tests on your presenter without real back-end and server logic
Scale your server side if needed.
You will be able to send less data to client if you make some required calculations on server side
Regarding #3, with passive-view pattern, there is a Presenter, which requesting data (sometimes it called Model), prepare it to display and send to View to render. In Model-View-ViewModel pattern, ViewModel will send request to server and prepare data to display. The difference between MVVM and PassiveView how Presenters and ViewModels are working with View. In PassiveView Presenter will know about View's interface to be able to send data to render. In MVVM View knows about ViewModel and bind data from ViewModel.
The last one, #1. I think yes, it is some Infrastructure layer. If you make an abstraction here, you will be able to move some optimization commands, set loading options (EF is very flexible here) and you will be able to do it quickly.
Related
We are writing a MVC data maintenance application is part of a larger project. We try to use domain-driven design DDD.
There are already other questions about this on SO, like here, here and here.
Yet they don't fully answer my question.
We also have bounded contexts in the data layer, since the database has 755 tables. So we created bounded contexts for business, roles, products, customers, etc.
The problem we have is that in the MVC application we have a view for "intial setup" which uses a ViewModel that in the end spans multiple bounded contexts (using IUnitOfWork pattern in Entity Framework 6).
That view must therefore write to the business context, and roles context.
The domain model would have a Business model and an Address model and a few other models in a larger pbject graph.
The ViewModel is a flattened, simplified model of these two and other domain models:
public class InitialSetupViewModel
{
string BusinessName{get;set;}
string Street{get;set;}
string Street2{get;set;}
string State{get;set;}
string ZIP{get;set;}
...
}
This ViewModel should map to the domain models, which we are doing with Automapper.
The controller gets the domain service injected:
public class SetupController : Controller
{
private readonly IMaintenanceService service;
public SetupController( IMaintenanceService maintenanceService = null )
{
service = maintenanceService;
}
public void Create(...????....)
{
service.CreateBusiness(..?.);
}
}
Problems:
The service can't know about the InitialSetupViewModel, so what should be passed to the service?
The service must know about the BusinessDbContext and RolesDbContext. So I must call SaveChanges() on both, which beats the purpose of having a single IUnitOfWork. Do I have to create yet another UnitOfWork that includes both business and roles entities?
I don't think it's justifiable to combine these two IUnitOfWorks into one just to make this MVC view work. But what is the solution?
Thank you!
It's always hard to have a strong opinion about a domain you don't know, but here it goes:
As has been commented already, the Controller should assume responsibility for mapping between view and domain models, DTOs or what have you. It could take an instance of InitialSetupViewModel as input, but implementation details may vary.
It is true that remodeling the domain may be the correct choice if you find yourself in need of otherwise breaking the borders of your bounded contexts. Focusing just on the Unit of Work pattern though, I don't quite get your hesitation.
It is the responsibility of a Unit of Work implementation to keep track of all the domain objects that need to be in sync within one transaction. There is nothing odd about the same domain object(s) being involved in several different Units of Work. This does not mean that you should combine "smaller" Unit of Work implementations into "larger" ones when you're dealing with another type of aggregate, but including both "roles" and "businesses" in one Unit of Work, sure.
Doing this should not be enticed by what your view looks like, but by what is "true" in your domain model(s), and rather than dealing just with collections of domain objects, your domain should probably describe suitable aggregates.
Maybe it's even OK to store each domain object with separate transactions (Units of Work), i.e. if synchronizing them is not necessary -- e.g. it's still fine if (or perhaps even desired that) failing to persist Business does not stop Roles from getting through or vice versa. Actually, I think one could even argue that if the bounded contexts are in fact correctly defined, this should be the case.
I hope these comments help.
Martin Fowler on Unit of Work and Aggregates.
I have a view model which should check that label of a new entity is unique (not in DB yet).
At the moment I've done it in the view model class:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (PowerOrDuty != null)
{
if (PowerOrDuty.Identifier == null)
{
using (var db = new PowersAndDutiesContext())
{
var existingLabels = db.PowersAndDuties.Select(pod => pod.Label);
if (existingLabels.Contains(PowerOrDuty.Label))
{
yield return new ValidationResult("Cannot create a new power or duty because another power or duty with this label already exists");
}
}
}
......
Please note that this is a small internal app with small DB and my time is limited, so the code is not perfect.
I feel that DB access from view models might be a bad practice. Should view model have direct DB access? Should it be able to call a repository to get the available labels? Should validation requiring DB access be done in a controller instead?
Should view model have direct DB access?
I think this should be avoided at all cost
Should it be able to call a repository to get the available labels ?
This is not the concern of a ViewModel.
This would introduce some complexity in the testing of your ViewModel (which should almost need none) I guess it is a sign of trouble coming.
Should validation requiring DB access be done in a controller instead ?
Maybe, if by "DB" you mean "Repository". But what comes to mind is a separate custom validation class that you will be able to (un)plug, test, and reuse, in another controller for ajax validation, etc
I think that accessing DB from VM is not wrong... AFAIK it is not breaking MVC concept (since it is a presentation layer concept). Said that, it could be better if you have the Validate method provided by a Service Layer.
But all the logic related to the content of the ViewModel, it is better kept in the VM than in the Controller. Cleaner controllers is better.
Your view model should not be tied to your context, it only cares about displaying data and validating it after a submit. You can perform validation like a required field or a value in range, but you can't know if a label already exists in your database.
You can't also fetch a list of "forbidden labels" before displaying your form, in order to test your label afterwards, because that list could have changed during this time (another user updating you database).
In my opinion, validation at model level should focus on what it can validate without knowledge of the data source, and let your database notify you errors like submitting a duplicate value in a field which has an unique constraint. You'll catch exceptions coming from your database for errors like those, and manage them accordingly.
Anyway, i think there's no straightforward answer for a problem like this.
I personally like the ViewModels to be anemic -- simply classes with properties.
For custom server-side validation like this, I prefer it go either in a service, with the consumption of the service in your controller, or even behind a custom validator.
With a custom validator, you could even (optionally) execute the validation remotely. That gets a little more complex though, but I've done it using a generic remote validator that consumes an Ajax action method to perform the validation, and wire that up through both the client validator and remote validator (to ensure you have your validation logic in a single method).
But which ever way you go, I think it is more common -- and in my opinion, more clean -- to keep all logic out of your ViewModel. Even in a simple app, your ViewModel should be dumb to your database context. Ideally, only services (not necessarily web services, but just an abstraction layer) are aware of your database context.
This, to me, should be done regardless of the size of application. I think the effort and complexity (it only adds another assembly to your solution) is worth the abstraction you get. Down the road, if you happen to decide to consume your services from another application, or if you decide to swap out your database context, it's much easier with that abstraction in place.
Whats the difference between Model and ViewModel? I should use both of them or I better skip one of them? who grabs the data from the database?
I wonder whats the best/right way to take my data from the database.
One option is to have a DAL (Data Access Layer) and instantiate it in every controller,
fill with it the viewmodels like:
var viewmodel = Dal.GetArticles();
Another option is to let the model itself grab the information from the Database:
var model = new ArticlesModel();
model.GetArticles();
public void GetArticles()
{
var context = new DbContext();
_articles = context.Articles
}
Another similar option is to have a static DAL so you can access it inside every model,
so each model will have a method to grab the data using the static DAL class (Which contain a DbContext class inside to access the Database)
public void GetArticles()
{
_articles = DAL.GetArticles();
}
So the general question is if the model itself needs to grab the data from the database or the controller itself can have access to the DAL.
While someone is writing a more useful answer, I will quickly address your points.
Model is the data you want to display.
More often than not, you will want to use object relational mapping so most of your business object classes correspond to database tables and you don't have to manually construct queries.
There are plenty of ORM solutions available, including Entity Framework, NHibernate and (now dying) LINQ to SQL.
There is also an awesome micro-ORM called Dapper which you may like if bigger frameworks feel unneccessarily bloated for your solution.
Make sure you learn about the differences between them.
DAL is more idiomatic in .NET than classes that “know” how to load themselves.
(Although in practice your solution will very likely be a mixture of both approaches—the key is, as usual, to keep the balance.)
My advice is to try keeping your models plain old CLR objects as long as your ORM allows it and as long as this doesn't add extra level of complexity to the calling code.
These objects, whenever possible (and sensible—there are exceptions for any rule!), should not be tied to a particular database or ORM implementation.
Migrating your code to another ORM, if needed, will be just a matter of rewriting data access layer.
You should understand, however, that this is not the main reason to separate DAL.
It is highly unlikely you'll want to change an ORM in the middle of the project, unless your initial choice was really unfit for the purpose or you suddenly gained a traction of 100,000 of users and your ORM can't handle it. Optimizing for this in the beginning is downright stupid because it distracts you from creating a great product capable of attracting even a fraction of hits you're optimizing for. (Disclaimer: I've walked this path before.)
Rather, the benefit of DAL is that you database access becomes always explicit and constrained to certain places where you want it to happen. For example, a view that received a model object to display will not be tempted to load something from the database, because in fact it is the job of controller to do so.
It's also generally good to separate things like business logic, presentation logic and database logic. Too often it results in better, less bug-ridden code. Also: you are likely to find it difficult to unit-test any code that relies on objects being loaded from the database. On the other hand, creating a “fake” in-memory data access layer is trivial with LINQ.
Please keep in mind that again, there are exceptions to this rule, like lazy properties generated by many ORMs that will load the associated objects on the go—even if called within a view. So what matters is you should make an informed decision when to allow data access and why. Syntaxic sugar might be useful but if your team has no idea about performance implications of loading 20,000 objects from ORM, it will become a problem.
Before using any ORM, learn how it works under the hood.
Choosing between Active Record-style objects and a DAL is mostly a matter of taste, common idioms in .NET, team habits and the possibility that DAL might eventually have to get replaced.
Finally, ViewModels are a different kind of beast.
Try to think of them like this:
You shouldn't have any logic in views that is more sophisticated than an if-then-else.
However, there often is some sophisticated logic in showing things.
Think pagination, sorting, combining different models in one view, understanding UI state.
These are the kinds of thing a view model could handle.
In simple cases, it just combines several different models into one “view-model”:
class AddOrderViewModel {
// So the user knows what is already ordered
public IEnumerable<Order> PreviousOrders { get; set; }
// Object being added (keeping a reference in case of validation errors)
public Order CurrentOrder { get; set; }
}
Models are just data, controllers combine the data and introduce some logic to describe data to be shown in view models, and views just render view models.
View model also serves as a kind of documentation. They answer two questions:
What data can I use in a view?
What data should I prepare in controller?
Instead of passing objects into ViewData and remembering their names and types, use generic views and put stuff in ViewModel's properties, which are statically typed and available with IntelliSense.
Also, you'll likely find it useful to create ViewModel hierarchies (but don't take it to extremes!). For example, if your site-wide navigation changes from breadcrumbs to something else, it's cool to just replace a property on base view model, a partial view to display it and the logic to construct it in the base controller. Keep it sensible.
A model represents the structure you like your data in and is not concerned about the view which may consume it. A model's intend is purely that of representing the structure.
A model may contain properties irrelevant to the view consuming it.
A view-model is designed with the view in mind. A view-model is intended for a 1-to-1 relationship to a view. A view-model only contains the basic fields and properties the view it is intended for requires.
In general you would have your controller contact a repository (In your example your DAL) obtaining the data and then populating either a model or view-model with the results, sending it down to the view.
Model (Domain Model): is the heart of the application, representing the biggest and most important business asset because it captures all the complex business entities, their relationships and their functionality.
ViewModel: Sitting atop the Model is the ViewModel:The two primary goals of the ViewModel are
1. to make the Model easily consumable by the View and
2. to separate and encapsulate the Model from the View.
Eg.
Model:
public class Product
{
...............
}
public class Category
{
...........
}
ViewModel:
public class ProductViewModel
{
public ProductViewModel(List<Product> products, List<Category> categories)
{
this.Products = products;
this.Categories = categories;
}
public List<Product> Products { get; set; }
public List<Category> Categories { get; set; }
}
In my continuing journey through ASP.NET MVC, I am now at the point where I need to render an edit/create form for an entity.
My entity consists of enums and a few other models, created in a repository via LINQtoSQL.
What I am struggling with right now is finding a decent way to render the edit/create forms which will contain a few dropdown lists and a number of text fields. I realize this may not be the most user-friendly approach, but it is what I am going with right now :).
I have a repository layer and a business layer. The controllers interface with the service layer.
Is it best to simply create a viewmodel like so?
public class EventFormViewModel
{
IEventService _eventService;
public IEvent Event { get; private set; }
public IEnumerable<EventCampaign> Campaigns { get; private set; }
public IEnumerable<SelectListItem> Statuses { get; private set; }
// Other tables/dropdowns go here
// Constructor
public EventFormViewModel(IEventService eventService, IEvent ev)
{
_eventService = eventService;
Event = ev;
// Initialize Collections
Campaigns = eventService.getCampaigns().ToSelectList(); //extn method maybe?
Statuses = eventService.getStatus().ToSelectList(); /extn for each table type?
}
So this will give me a new EventFormViewModel which I'll bind to a view. But is this the best way? I'd essentially be pulling all data back from the database for a few different tables and converting them to an IEnumerable. This doesn't seem overly efficient, but I suppose I could cache the contents of the dropdowns.
Also, if all I have is methods that get data for a dropdown, should I just skip the service layer and go right to the repository?
The last part of my question: For the ToSelectList() extension method, would it be possible to write one method for each table and use it generically even if some tables have different columns ("Id" and "Name" versus "Id" and "CampaignName").
Forgive me if this is too general, I'm just trying to avoid going down a dead-end road - or one that will have a lot of potholes.
I wouldn't provide an IEventService for my view model object. I prefer to think of the view model object as a dumb data transfer object. I would let the controller take care of asking the IEventService for the data and passing it on to the view model.
I'd essentially be pulling all data
back from the database for a few
different tables and converting them
to an IEnumerable
I don't see why this would be inefficient? You obviously shouldn't pull all data from the tables. Perform the filtering and joining you need to do in the database as usual. Put the result in the view model.
Also, if all I have is methods that
get data for a dropdown, should I just
skip the service layer and go right to
the repository?
If your application is very simple, then a service layer may be an unneeded layer of abstraction / indirection. But if your application is just a bit complex (from what you've posted above, I would guess that this is the case), consider what you will by taking a shortcut and going straight to a repository and compare this to what you will win in maintainability and testability if you use a service layer.
The worst thing you could do, would be to go through a service layer only when you feel there is a need for it, and go straight to the repository when the service layer will not be providing any extra logic. Whatever you do, be consistent (which almost always means: go through a service layer, even when your application is simple. It won't stay simple).
I would say if you're thinking of "skipping" a layer than you're not really ready to use MVC. The whole point of the layers, even when they're thin, is to facilitate unit testing and try to enforce separation of concerns.
As for generic methods, is there some reason you can just use the OOB objects and then extend them (with extension methods) when they fail to meet your needs?
I am investigating WPF's MVVM design pattern. But am unsure where to put the Data Acess code?
In some examples I have looked at, data access is performed directly in the ViewModel. It seems odd to put something like linq to sql in the ViewModel? Other examples have a seperate project for Data Access, this seems more like it?
Is this there a general approach? I feel like I am missing something here!
Thanks
Here's how I've been organizing my MVVM w/ LINQ projects:
Model - I think of the Model as the state of the system. It provides an interface to the data, and it keeps track of system status. The Model does not know about the ViewModel or View--it just provides a public interface to its data and various events to let the consumers (usually ViewModels) know when the state has changed.
ViewModel - The ViewModel is in charge of organizing or structuring all the data needed by the View, keeping track of the status of the view (such as the currently selected row of a data grid), and responding to actions on the view (such as button pushes). It knows what the view needs, but it doesn't actually know about the view.
View - The View is the actual look and feel of the UI. It contains all the built-in and custom controls, how they arranged, and how they are styled. It knows about the ViewModel, but only for the purpose of binding to its properties.
Gateway - This is the part that directly addresses your question. The Gateway (which is basically my way of saying "DataAccessLayer") is its own separate layer. It contains all the code (including LINQ queries) to CRUD or select, insert, update, and delete data from/to your data source (database, XML file, etc.). It also provides a public interface to the Model, allowing the Model to focus on maintaining system state without having to concern itself with the details (i.e., the queries) needed to update the data source.
DataAccess Classes - In C#, these are very simple classes that model your elemental data objects. When you select something using a LINQ query, you will usually create an IEnumerable<T> or List<T> where T is one of your data objects. An example of a data object would be:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
The big advantage of a design like this is that it really separates your concerns. Everything has a specialized job, and it's (usually) pretty easy to know what kind of thing goes where.
The disadvantage is that it may be overkill for small projects. You end up creating a lot of infrastructure for public interfaces that basically pass a single wish through several layers. So, you might end up with a scenario like this: [user clicks Submit, ViewModel tells Model to AddNewPerson, Model tells Gateway to InsertPerson] instead of a scenario like this [user clicks Submit, ViewModel adds new record to the database directly].
Hope that helps.
I would add another layer, essentially what you want is a data factory. You want to create a set of classes that will CRUD to the database for you and return clean POCO objects to the ViewModel.
A good example to look at would the Nerd Dinner book. It covers MVC not MVVM but the patterns are very similar and the way they access data in that solution would be good starting point.
Hope this helps.
Data access should not be in the view model, as this is supposed to be a view specific (possibly simplified) representation of the domain model.
Use a mapper of some sort to map your view model (the VM in MVVM) to your model (the first M). New objects in your model can be created using the factory pattern. Once created, you can store them in a database using the repository pattern. The repositories would then represent your data access layer. In your repository you could use an O/R mapper like NHibernate or Entity Framework.
EDIT:
I see that GraemeF suggests putting the data access code in the model. This is a NOT a good approach, as this would force you to update your domain model if you were to move from e.g. SQL Server to Oracle or XML files. The domain objects should not have to worry about how they are persisted. The repository pattern isolates the domain from its persistence.
MVVM stands for Model, View, and ViewModel. The piece you are missing is the Model, which is where your data access code lives.
The ViewModel takes the Model and presents it to the View for display, so typically you would have something like this:
class PersonModel : IPerson
{
// data access stuff goes in here
public string Name { get; set; }
}
class PersonViewModel
{
IPerson _person;
public PersonViewModel(IPerson person)
{
_person = person;
}
public Name
{
get { return _person.Name; }
set { _person.Name = value; }
}
}
The PersonView would then bind to the properties of the PersonViewModel rather than directly to the model itself. In many cases you might already have a data access layer that knows nothing about MVVM (and nor should it) but you can still build ViewModels to present it to the view.
Your ViewModel should be a thin layer that just services the view. My rule of thumb: if it has to do with the presentation of the UI, then it belongs in the ViewModel, otherwise it should be in the Model.
The WPF Application Framework (WAF) contains a sample application that shows how the Model-View-ViewModel (MVVM) pattern might be used in combination with the Entity Framework.