I have to set up a Asp.net demo using MVC 4 in a web application in order to help decision for a product that currently don't use this pattern. The model, view and controller should be simple, I just have two or three entities and a few pages.
I suppose I don't have to implement the whole infrastructure with services, repositories, etc. So how could I simplify the MVC components without loosing those advantages?
The MVC components aren't related to the data access strategy which you can use. To put together a quick demo (or a simple application) you can leave the data access in the same project but eventually split that out etc.
You can use something like AutoMapper to map from your entities to your view models if you want to put that level of abstraction in. You can also use EntityFramework contexts in the controllers to avoid additional levels of abstraction and only put in a simple interface/abstraction into one controller to show unit test ability.
Small examples of different patterns which could be used in the application is probably the way to go for the demo/presentation and not worry too much about putting them in all over the place. Remember the presentation and the delivery of information is as important, it not more, than the demo code itself.
Related
I'm aware that in model-view-controller, the Model is the class part.
If I have a User class and instantiate an object, the object must refer to a single user from the database.
So I'll have the CRUD methods on the user, for that specific user.
But if I need a function to run a SELECT * FROM Users, should I create a function within the User class? Or a function in a helper file? Or in the controller? Where should it go, in order to respect the MVC pattern?
I mean, it makes no sense to instantiate a User object just to run a function to display the Users table.
I'm not sure if this will raise "primarily opinion based" flags. I just don't know where those functions should go. If you guys consider the question worth closing, it's ok. But tell me in the comments in which stack community I should ask this.
Back up a bit. Let's go foundational for a moment.
In the MVC pattern
The model is your state (in simple terms), meaning a representation of the data important to the business functionality you are working with
The view is a way of presenting the state to the user (NOTE user here could be another system, as you can use MVC patterns for service endpoints)
The controller ensures the model gets to the view and back out of the view
In a system designed with good separation of state, business functions are not present in the model, the view or the controller. You segregate business functionality into its own class library. Why? You never know when the application will require a mobile (native, not web) implementation or a desktop implementation or maybe even become part of a windows service.
As for getting at data, proper separation of concerns states the data access is separate not only from the model, view and controller, but also from the business functionality. This is why DALs are created.
Before going on, let's go to your questions.
should I create a function within the User class? This is an "active record" pattern, which is largely deprecated today, as it closely couples behavior and state. I am sure there are still some instances where it applies, but I would not use it.
Or a function in a helper file? Better option, as you can separate it out. But I am not fond of "everything in a single project" approach, personally.
Or in the controller? Never, despite Scott Gu's first MVC examples where he put LINQ to SQL (another groan?) in the controller.
Where should it go, in order to respect the MVC pattern?
Here is my suggestion:
Create a DAL project to access the data. One possible pattern that works nicely here is the repository pattern. If you utilize the same data type for your keys in all/most tables, you can create a generic repository and then derive individual versions for specific data. Okay, so this one is really old, but looking over it, it still has the high level concepts (https://gregorybeamer.wordpress.com/2010/08/10/generics-on-the-data-access-layer)
Create a core project for the business logic, if needed. I do this every time, as it allows me to test the ideas on the DAL through unit tests. Yes, I can test directly in the MVC project (and do), but I like a clean separation as you rarely find 0% business rules in a solution.
Have the core pull the data from the DAL project and the MVC project use the core project. Nice flow. Easy to unit test. etc.
If you want this in a single project, then separate out the bits into different folders so you can make individual projects, if needed, in the future.
For the love of all things good and holy, don't use the repository pattern. #GregoryABeamer has a great answer in all respects, except recommending you create repository instances to access your entities. Your ORM (most likely Entity Framework) covers this, and completely replaces the concepts of repositories and unit of work.
Simply, if you need something from your database, hit your ORM directly in your controller. If you prefer, you can still add a level of abstraction to hide the use of the ORM itself, such that you could more easily switch out the data access with another ORM, Web Api, etc. Just don't do a traditional unit of work with tens or hundreds of repository instances. If you're interested, you can read a series of posts I wrote about that on my blog. I use the term "repository" with my approach, but mostly just to contrast with the typical "generic" repository approach you find scattered all over the interwebs.
I'd use some kind of 'Repository' layer. Then, my controller calls the UserRepository GetAll method and sends the data to View layer.
I know this has been sort of answered in various posts, but using VS2012 with MVC4, I wonder if there is a more updated method or new ways to do things.
I have a large enterprise application that has 22 projects in it. It has a complex large business object/logic project and has multiple presentation layers. Working on a new presentation layer using MVC 4. I have never used MVC before at this scale.
Here are my questions:
How do people handle the model in this scenario? All the Microsoft examples are so simple.
I have seen posts to auto mappers and recommend deves use simple models and extract from the BO layer, but some of these tools like auto mapper seem to have gone idle, is there a library in MVC that does that now?
I'm just trying to figure out best practices before I get started, seems usually I figure them out after the fact.
I break my MVC apps into several different projects.
AppName.Configuration: to handle any configuration of the app (i.e. pulling in web.config/app settings, etc)
AppName.Data: this is the data layer where all DB access is performed (no business logic). The DBML/EDMX lives here, my repository class(es) live here as well.
AppName.Models: this is where all of my ViewModels are defined for MVC, as well as other model objects needed throughout the application.
AppName.Services: This is my business layer, all everything must pass through here to get to the data layer or to the presentation layer. ViewModels are constructed from the database objects, data validation happens here, etc.
AppName.Web: this would be the MVC application.
AppName.Data.Test: Unit tests for Data app
AppName.Services.Test: Unit tests for the services
AppName.Web.Test: Unit tests for the MVC controllers
AppName.Web.UI.Test: Unit tests for the web user interfaces (using WATIN)
I don't use any auto-mappers, as i clearly define a specific viewmodel for each view of the application. If it isn't needed for the view, it doesn't go in there.
Most MVC examples are so basic, they show everything in the web app (data, models, business logic in the controllers, etc.)
I hope this helps.
does it make sense to use KnockoutJS Viewmodels in combination with ASP.NET MVC3 or 4? Because it is not very DRY, isn't it? I have to write models for EF, Viewmodels for the MVC Views and Viewmodels for Knockout... and i lose a lot of magic. Automatic client-side validations for example.
Does it make sense to use MVC at all if one sticks with the MVVM Pattern?
With Knockout Mapping, you can automatically generate a KO view model from your MVC view model.
This is a proper pattern: your models are raw entities, your data. Your views are the UI. And your view models are your models adapted to that specific view.
This may be an unpopular answer, but I don't use ko.mapping to translate my C# POCOs into JS viewmodels. Two reasons, really.
The first is a lack of control. ko.mapping will turn everything into an observable if you let it. This can result in a lot of overhead for fields that just don't need to be observable.
Second reason is about extensibility. Sure, ko.mapping may translate my C# POCOS into JS objects with observable properties. That's fine until the point you want a JS method, which at some point, you invariably will.
In a previous project, I was actually adding extra methods to ko.mapped objects programmatically. At that point, I questioned whether ko.mapping was really creating more problems than it solves.
I take on board your DRY concerns, but then, I have different domain-focused versions of my POCOs anyway. For example a MyProject.Users.User object served up by a UserController might be very different from a MyProject.Articles.User. The user in the Users namespace might contain a lot of stuff that is related to user administration. The User object in the Articles namespace might just be a simple lookup to indicate the author of an article. I don't see this approach as a violation of the DRY principle; rather a means of looking at the same concept in two different ways.
It's more upfront work, but it means I have problem-specific representations of User that do not pollute each others' implementations.
And so it is with Javascript view models. They are not C# POCOs. They're a specific take on a concept suited to a specific purpose; holding and operating on client side data. While ko.mapping will initially give you what seems to be a productivity boost, I think it is better to hand-craft specific view-models designed for the client.
btw, I use exactly the same MVC3/KnockoutJS strategy as yourself.
We use knockout Mapping to generate the KO view models well.
We have a business layer in a separate project that does CRUD, reporting, caching, and some extra "business logic". We aren't going to be using EF, or something similar. Currently we've defined c# classes as MVC models, and our controllers call the business layer to construct the Models that are defined in the usual place in our MVC app. These C# models get serialized as JSON for use in our pages.
Since everything we do in the browser is c#/JSON based using knockout, we aren't using MVC models in the traditional MVC way - everything gets posted as JSON and serialized to c#, so we don't use MVC model binding, validation, etc. We're considering moving these models to our business layer so they can be tested independently of the web app.
Se we'll be left with an MVC app that has controllers and views, but no models - controllers will get models that are defined in the business layer. We're nervous about departing from the normal MVC structure, but a KO/javascript based client is fundamentally different from a DOM based client that MVC was originally built around.
Does this sound like a viable way to go?
I work now on project which mixes MVC3 and knockouts and I have to tell you - it's a mess...
IMO it's nonsense to force some patterns just to be up to date with trend.
This is an old topic, but now in 2014 (unfortunately) I still feel this question has a huge relevance.
I'm currently working on a project which mixes MVC4 with knockoutjs. I had some difficoulties to find whichs part should be handled on which side. Also, we needed a "SPA-ish" kind of architecture, where each module has its own page, but then inside that module there is only AJAX interaction. Also faced some heavy validation scenarios, and needed to provide user (and SEO) friendly URLs inside each module. I ended up with the following concept, which seems to be working well:
Basic MVC and .NET side roles:
Handling authentication and other security stuff.
Implementing the Web API interface for the client-side calls (setting up viewmodels, retrieving and mapping data from the domain, etc.)
Generating knockout viewmodels from my (pre-existing) C# viewmodels with T4 templates, also including knockout validation plugin extensions from .NET validation attributes. (This was inspired by this aticle). The generated viewmodels are easily extensible, and the generation can be finetuned with several "data annotation"-like custom or built-in attributes (such as DefaultValue, Browsable, DataType, DisplayFormat, etc.). This way the DRY doesn't get violated (too much).
Providing strongly typed, but data-independent partial view templates for each submodule (each knockout viewmodel). Because property names on C# viewmodels are same as in KO models, I can benefit from the strongly typed helpers specifically written for KO bindings, etc.
Providing the main view for each module similarly to previous point.
Bundling and minification of all scripts and stylesheets.
Basic client-side roles:
Loading the initial state of all viewmodels encapsulated into one module page, taking the whole URL into account with a simple route parser implementation.
Handling history with history.js
Data-binding, user interaction handling.
Posting relevant parts of viewmodels to the server, and processing the returned data (usually updating some viewmodel with it).
I hope this could help anyone else who feels lost in the world of trendy technologies. Please, if anyone has any thought on this, feel free to post any question or suggestion in the comments.
We have 3 websites at the moment that all operate off the same database backend and they share almost 100% of the business logic.
It is becoming a pain to have to update 3 website's code every time to accommodate a small change. Would using ASP.Net MVC work for us?
What I am thinking is the business logic and database is almost identical in all 3 so extract that away into the Model and the Control. Then each web front end (which looks different) each has a different View. It would then be Nice to have a single project where we can have all the code for the Model and Control shared. And 3 different views.
How would we deploy something like this? Share a single codebase for Model and Control and have 3 separate URLs using 3 different Views. Or is there a better way to do this?
You can probably pull it off using ASP.NET MVC, but you could also insert a service layer and use standard ASP.NET web services to expose it. Then each of your "views" could still be in its own little world, and just use the web services to grab and persist data.
ASP.NET MVC is probably a better solution in the end, but this is certainly an alternative.
One thing you do need to consider is if you want to keep these 3 sites on seperate domains. I'm not sure how ASP.NET handles keeping different views on different domains.
Sounds like you really need to implement a service layer (encapsulating the common business logic and data) that is used by n (thin) web apps. So think SOA.
This seems reasonable to me. In terms of the model and control you could consider dealing with any minor differences between the current models/controls using shared functionality in a base class and using inheritence to deal with exceptions.
If your web front end is only different in terms of look and feel then you may want to consider using the same code base but just swapping in different themes using CSS.
We're building about 10 ASP.NET MVC sites which have a common set of features (and corresponding URLs, Routes, Controllers, Actions, and Views). The sites will also all share a base set of domain objects (e.g. users, companies) and base attributes on those objects (e.g. name, address, etc.).
But each site will also be highly customized and extended from the base. For example, our site for large, public companies will have "Subsidiary" and "Stock Symbol" fields on the Company domain object, while our site for startups will have a "Venture Firm" and and "Funding" attributes. Look and feel will also vary considerably, although we're trying to keep HTML as consistent as possible (modulo extra form fields for extra domain object attributes, etc.). We'll also be overriding images sparingly, so we can, for example, re-use the same button graphics across sites.
Anyway, we're trying to figure out how best to factor and architect things so that we can reuse as much code and as many tests as possible without limiting our freedom to add per-app attributes and vary the UI between apps.
I'm familiar with how to handle limited-customization multi-tenancy like you find in StackOverflow/SuperUser/ServerFault (or MSDN/TechNet for that matter), where the UI is a little different and the data model is more-or-less identical. But when the models and UI are very different (but inherit from a common base), I'm less sure how to proceed.
I'm less worried about operational issues, since we'll probably be running each site in a separate appdomain and hosting them on separate databases. I'm more worried about reducing long-term code maintenance costs, increasing agility (e.g. easy to add new features to the base without breaking derived apps), and realizing short-term dev-/test-cost savings as we build our 2nd, 3rd, 4th, etc. site.
I'm looking both for high-level guidance and suggestions, but also concrete suggestions for how to make that guidance real using modern ASP.NET MVC practices.
I realize this is a very general question, but for starters I'm looking for both high-level guidance as well as concrete tips-n-tricks for how to apply that guidance with ASP.NET MVC, including things like:
recommendations where to split base/derived across Visual Studio projects
source control tips to avoid forking
database schema tips (FWIW, our databases are all small-- under 10K rows per table, so dev/test cost is more of an issue than DB perf)
tips about re-using Controllers/Views/etc. corresponding to the "base" model attributes, especially re-using UI for things like "new customer" forms which will have a mix of base and derived attributes.
Anyone have good advice for how to architect a multi-tenant app like this?
Here's what we do, and it works pretty well for about 8 sites currently.
Define a core MVC project for your Controllers, ViewModels, HttpApplication, routes, etc. This will compile into a DLL and compromise the bulk of your site.
Create a basic set of default views, scripts, images, etc. for your site. These will server as defaults for your individual sites.
Per client, create any custom controllers, routes, etc that you'll need in a project that compiles to another dll.
Also per client, recreate any views, scripts, images that you'll want to use.
To make the above steps work together you'll need to write a little glue. The first piece of glue is a custom view engine. You'll want to customize the standard view engine to first look for views in your client-specific folder, and then the default folder. This lets you easily override the default layout per client.
The second method of getting everything working is to have your core application load the routes, controllers, etc from your client specific assembly. To do this I use the Managed Extensibility Framework (MEF) to expose a single Register method. Calling this method on my client assembly code registers the routes and any other client-specific needs.
Here's a general view of what my site folder structure looks like, with SiteContent being checked for views first:
- AppContent
- AppContent/Static
- AppContent/Static/Images
- AppContent/Static/Scripts
- AppContent/Static/Styles
- AppContent/Views
- AppContent/Views/Shared
- SiteContent
- SiteContent/Static
- SiteContent/Static/Images
- SiteContent/Static/Scripts
- SiteContent/Static/Styles
- SiteContent/Views
- SiteContent/Views/Shared
- web.config
- Global.asax
I have helpers that I can use like SiteImage and AppImage for use in my views. Also, I make each of my client sites use certain specific names for their master pages, that I don't ever define in my AppContent defaults.
I realize this is a rough overview, but it is working well enough for us right now.
I'm involved in a similar type of "suite" of projects currently which is focused on allowing customers to apply for products online but have very similar requirements for what information to collect, where the only differences are around product specific pieces of information or slightly different legislative requirements.
One thing that we have tried to do is create pages (model, view and controller combinations) that are reusable in themselves, so any application can use the page to capture information but redirect to the next page which may be different depending on what type of product is being applied for. To achieve this we are using abstract base controllers in the form of the template method pattern that contain basically all the required controller logic (including action methods with their applied action filters) but then use abstract methods to do the specific stuff such as redirecting to the next page in the process. This means that the concrete implementation of the controller used by specific application page flows may contain only one method which returns a RedirectToActionResult corresponding to the next page in the flow.
There is also quite a bit of other stuff that handles going backwards and those kinds of navigational things, but with the help of action filters you can get it set up that you don't have to worry about it once you get it up and working.
There are also base model objects which contains common functionality, be it validation logic or state persistence logic.
The data captured during the application process is persisted in database as xml serialized model objects which can then be pulled out and de-serialised once the application is completed and spat out in whatever format to whatever system the backend operations staff use to process applications.
The implications of this is that we have a project structure that consists of a base dll that contains top level abstract classes, interfaces and utility classes as well as html helpers, action filters etc. Then we have mvc projects which contain the concrete implementations of the base controllers, models etc as well as the views and masterpages.
The hardest thing is sharing views and I don't think we have properly got this sorted yet. Although with MVC 2.0 containing Areas I think this will become less of an issue but I haven't had a good play with it yet. (see Scott Gu's post on 2.0: http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx)
One thing I have POCed that looks like it will work is using a base MVC project to contain common views and then extending the default view engine to search that project on the web server when looking for a view to render (which is quite easy to do). Areas though is a far nicer solution.
As for source control, we are using svn and I think you are reasonable in being concerned about branches. It is not something that we have had to deal with yet, but we are probably going to go with git as it seems to make the process of branching and merging much less painful.
Not sure whether this helps you much but I would definitely recommend keep in mind abstract controllers and models, and also look at how you can use html helpers and and partial views to group similar pieces of functionality.
Mike Hadlow goes into good detail on how to accomplish this:
http://mikehadlow.blogspot.com/2008/11/multi-tenancy-part-1-strategy.html
One way to do this is to use branching in a source control system.
The main branch is for the common functionality. You then have a branch for customization and can merge changes out to the customization or back to the main branch.