I am working on a project with ASP.NET MVC, Web API and Angular JS.
I am considering changing the project structure from classic MVC (folder wrap files of the same type - controllers, etc) to feature folders:
So these folders can be described has follows:
Assets: images, fonts, ...
Features: list of features (blog, home, shared, ...)
Shared hold common files to all features; A feature might contain:
A) Angular controllers and services;
B) ASP.MVC controllers, models, model validators;
C) Specific CSS styles used in feature.
Handlers: service layer handlers that handle messages (commands, etc);
Helpers: infrastructure files;
Messages: service layer messages (commands, etc);
Scripts: vendor scripts (Angular, Jquery, etc);
Styles: global styles (reset.css, etc);
PROBLEMS
On Blog feature I will show a list of posts.
BlogController calls PostService(?) that gets posts from the API?
Each returned post has a title, a body and tags to display.
On Home I display recent posts but only the titles.
So HomeController calls HomeService or a PostService inside Post feature?
Imagine on blog feature I editing a new post.
In Blog controller I call the PostService to get that post.
But I need to fill a select list with the Tags.
So I need a TagsService and a TagsController in Blog feature?
These 2 questions might seem strange but they help me to resolve a lot of doubts I have with this way of organizing an application.
Any suggestions?
Feature folders are great, especially in the long run.
I suggest to keep together everything related to a certain feature, including handlers.
Rethink the Services. In most cases they are not needed (unless you're exposing services for clients).
Rename Helpers to Infrastructure.
Checkout MediatR
Related
I have seen several integrations between wordpress and symfony, but they are made with the goal of managins static pages content inside wordpress and symfony acting as the controller.
Wordpress plugin development api seems really basic and primitive and you have no way o code with the MVC pattern out of the box. So the big question is, what would be an starting point to create plugins in wordpress, and create admin sections in it, but using Symfony power to manage database access, form creation and validation, etc .....
I had briefly considered a similar approach for integrating Lithium with WordPress, but ran into a great deal of hurdles that made another approach seem more worthwhile: create an MVC framework that was specifically designed to work inside of WordPress.
It's not yet as full-featured as Symfony, Rails, etc, but WP MVC has similar architecture to the major MVC frameworks and should be easy to pick up if you're familiar with them. It ties in directly with existing WordPress functionality. When you create scaffolding for a resource, for example, the code that's created includes an admin controller and admin views (which look similar to WordPress's native index/add/edit views for posts), as well as the appropriate WordPress routing and a public controller and public index/show views to display the resource on the public side, within the active theme.
There's more info on it on its WordPress Plugins page, and its brief tutorial may make it seem less abstract.
I have a large custom ecommerce engine that is currently using a SQL Server database (stored procedures handling most data tasks), a WCF middle-tier (handling business logic), and an MVC front-end site (that has no knowledge of any database). Our need for a content management system is increasing rapidly and I'm trying to figure out the best way to implement one, considering our very taxed development resources.
My first thought it to simply have two websites, an Orchard CMS site and our e-commerce site. I could setup some type of request routing that would send URLs for catalog browsing and cart functions to the ecommerce site, while other URLs get handled by the Orchard site. I would have to have a couple of modules (or widgets) built within the Orchard site that would display things like the cart summary that appears in the heading of each page. This seems like the easiest method of handling this, even if it is short-term.
My other thought is to have the site completely built using Orchard. This would require porting our ecommerce logic into modules. This seems like it would be one hell of a task. All of our work is done via web services, so if a user goes to a specific category URL, the site would call a web service and pass some variables (customer ID, category, etc). The web service would return the categories, products and prices for that customer - which would then be displayed on the screen.
Lastly, an even more complex version of the last option would be to actually store the products in Orchard, so that editable fields (description, meta tags, etc) would be managed through the Orchard CMS. This would require major changes to (or absorption of) our WCF middle-tier. This seems like it would be almost impossible, but may allow better handling of more media down the road (photos, videos, MSDS sheets, product literature, etc).
What are your thoughts so far, between these three models.
You can create a simple Orchard module that is a lot like an area in an MVC project. It uses controllers and views and is easy to do if you're familiar with MVC. You don't need to integrate it very heavily with Orchard if you don't want too. Your module's content would be in a folder and Orchard would manage the rest of the site's content.
To make the pages in your module use the orchard theme from the site you just need to add the [Themed] filter to your controller.
The hello world example in the Orchard Documentation shows you how to do this.
This would be the easiest option, but there would be benefits if you decided to store the products as Orchard content items. It would be more difficult to get there, but you'd be able to take advantage of other Orchard modules and add content parts like tags, comments and reviews to your products.
Whats your best practice (within MVC) with how you work with front-end-developers and back-end-developers?
Take this example: The team of 3 (1 front-end and 3 back-end) have 10 modules to develop on a homepage. All modules require HTML, CSS, Images as well as controllers and models.
How would you usally set up your workflow?
If I as a front-end-developer design a module without a proper controller and model, how do I best work with dummie-variables? Best to not use variables and just put "lorem ipsum" in my views? Or should I create a temp-model with set values to not have to edit the view after the back-end-developers are done?
Is it better as a front-end-developer to wait until you have all the modules and controllers you need OR maybe work at the same time on a homepage module?
Thanks for sharing!
For me backend is the domain and the service layer which comes in a separate assembly. Frontend is Controllers, ViewModels and Views. So backend developers start by defining the model objects and service interfaces and provide the frontend developers with this assembly. They could also provide a dummy implementation of the service interface which simply returns hardcoded values. So the frontend developers could now start designing the controllers which would consume the services, map the domain models to their corresponding view models and pass them to the views. Once the backend developers have finished implementing the service interfaces they provide the frontend developers with the new version of the assembly and the frontend developers simply switch their DI framework to point to the new implementation instead of the dummy one.
You could also have some frontend developers working on a reusable framework of HTML helpers, extension methods, ... which will be used all along the project.
My workflow goes as follow:
Back-end developers creates views using proper XHTML markups, without high styling. They are making only mockup.
Front-end developers creates CSS classes, styles, etc.
When Back-end developers have finished their work and Front-end developers have all styles done, then it's time to merge. All styles are applied to mockups, and some corrections are applied.
I've been reading mako / pylons documentation and am having trouble finding good examples / discussion of integrating multiple applications into a single page, so for example, if i had a blog application and an application which just selects a random quotation from a database of awesome quotations. (the example is trivial, just for exposition)
So I want to make a single page which displays both applications,
I'm not sure how to go about writing the templates, i've seen next.body(), do I need to call the controller from the application in a template?
How could I do this on the fly?
Can I just make a model describing the page, and have each application it wants to call as objets in the attributes of the model?
I'm just spitballing here, hoping for a pointer to an example / tutorial i can look over.
Thanks for any advice.
In Django, "applications" are components you develop or choose, then customize, mix and match together to get your final website.
In Pylons, "application" refers to the whole thing you're creating--controllers, models, templates, middlewares, any helper modules, documentation etc. A Pylons application is a bunch of code that can be served as-is by Paster, Apache/mod_wsgi or any other WSGI-supporting web server.
In Pylons, to get, for example, blog posts and random quotations in single page, you'd:
Create separate models for representing and manipulating blog entries and quotes, like myapp.model.Post, myapp.model.Quotation.
Create a controller action that queries models to get X blog posts and a single quotation, put them in data object that will be passed to template.
Create a template that displays both blog posts and quotation on single page. This template can, of course, inherit from some base template or include template fragments, so you don't have to copy-paste common HTML code across many templates.
Hope this helps!
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.