I've been looking at Groovy on Grails and noticed a line at the bottom that says:
Grails aims to bring the "coding by convention" paradigm to Groovy.
What exactly is coding by convention?
Convention over Configuration (aka Coding by convention) is a software design paradigm which seeks to decrease the number of decisions that developers need to make, gaining simplicity, but not necessarily losing flexibility.
The phrase essentially means a developer only needs to specify unconventional aspects of the application. For example, if there's a class Sale in the model, the corresponding table in the database is called sales by default. It is only if one deviates from this convention, such as calling the table "products_sold", that one needs to write code regarding these names.
When the convention implemented by the tool you are using matches your desired behavior, you enjoy the benefits without having to write configuration files. When your desired behavior deviates from the implemented convention, then you configure your desired behavior.
From "Convention over configuration" article on Wikipedia.
In the context of Grails, "coding by convention" means that a lot of (tedious and repetitive) explicit code and/or configuration is replaced by simple naming and directory structure conventions. For example:
Any class whose name ends with Controller in the grails-app/controllers directory is automatically a Spring controller and closures defined in it will be bound to URLs - you don't have to configure this in an XML file as you would have to when using pure Spring.
The same goes for taglibs (grails-app/taglib directory) - no more tedious TLD files!
Domain classes in grails-app/domain probably have the most "convention magic", being automatically mapped to an automatically generated DB schema - with DB table and column names being by convention identical to the domain property names.
Coding by convention vs coding by configuration:
The idea that you have certain placing or naming conventions for stuff so you don't have to explicitly tell the program where stuff is or what it is called.
For example, in ASP.Net MVC there is a convention for where the views are stored and what they are called. This means that when your code instructs the server to return a view, the runtime will look for a view with a certain naming structure in certain folders. See page 20 in this pdf for more clarity.
Another example would be naming conventions for methods. For example, in an event-driven language you could have a choice to explicitly declare which method handles which events or you can rely on a naming convention - like ..._OnOpen or ...OnClick and then rely on the runtime to figure out the correct method to call for a given event.
Lots of conventions here:
How to name HTML elements so they're easily accessible as parameters from the HTTP request;
How to relate object attributes to table and column names in the database;
How to arrange a project into directories/packages;
It's what you do when you find yourself solving a common problem in a particular style. You notice similarities and codify them into some automation scheme.
See Convention over Configuration. It's the concept of designing a tool or framework to have the most common configuration options as the defaults, so for the vast majority of users no configuration is required.
It means if you stick to certain coding conventions as defined by whatever convention-based framework you are using, you get a lot of functionality for free. In other words, if you structure your application in accordance to what the framework expects, a lot of work can be saved.
It would be a good idea to look up the advantages and disadvantages of coding by convention.
Related
In French, a "donkey bridge" is some apparent difficulty in a subject to be learnt that throws off newcomers - the donkeys. The expression is used with patronizing assurance by educators who know the difficulty is apparent, not real, and the donkeys just have to cross the bridge.
Well I'm the donkey, and I'm having real trouble settling down with the folder structure and "virtual" urls of asp.net mvc projects. Urls are now a blend of pseudo-path information, encoded in routes, and arguments, that resolve to controller classes that, being classes, have no notion of their directory. So, it seems, there is no simple way of using relative paths/urls to reference static resources associated with a dynamic page: script file, stylesheet, razor view, images. .Net helpfully gives me default search locations for views, and default folders for "Content", "Scripts", "Images". I get the feeling they want me to file things by type. But this obliges me to invent file and subfolder names in each of these locations, then to hardcode the resulting paths in the controller and the view. Since a given controller generally has only a handful of tightly coupled views, and 99.9% of views have 1 script file and 1 stylesheet, all this name invention, and categorization by type, introduces needless brittleness and complexity, and masks any expression of what the project actually does.
Is anyone else fighting this? Is their a tried-and-tested strategy for naming in large mvc projects that
Expresses what the project does at the top level of the folder structure (or any level of the folder structure!).
Provides a default location or generated names for .cshtml, .js and .css, such that I don't need to search through code to find the names of associated resources.
Preserves the flexibility and decoupling of naming/indirection where this has proved useful.
I'm aware of areas as a way subdividing an mvc project into functional groupings, but this just seems to recreate the problem inside each area. I've looked at this method for customizing the search location for views, but there's no dynamic element. I've implemented a view engine to have fine-grained run-time control over the view path, which is fine if you're brave but I'm still unsure how best to use it, and I'm put off by the potential caching issues. For all the dissing of opinions, I'm particularly interested in answers addressing what I should do.
Thanks to all the downvoters, intolerant village folk. The donkeys that refused to cross the bridge are right, and they're all hanging out in a green field, munching happily on Nancy and building fabulous Owin pipelines. Feature folders are the future.
I agree with you that trying to arrange elements by type is usually problematic. For example putting C# interfaces for a customer and a product in the same "Interfaces" folder is not something I am keen on personally, I'd rather have a Customers folder and a Products folder, each with an Interfaces folder inside.
However, with MVC, there is a lot of enforced and unenforced convention in place which you will probably have to live with. As an example, if you have a controller called ProductContoller, it will automatically look for views in the Views\Product folder. So your product index.aspx/cshtml view is nicely segmented from your other index views.
For things like scripts and CSS, these are not enforced and technically you could put them anywhere, but it's a convention across many web frameworks to keep them in the same root folder. In some frameworks you would be explicitly allowing public access to certain folders to read files, so you'd want to do this for all scripts or CSS files together.
It's not an answer but I hope it helps.
then to hardcode the resulting paths in the controller and the view
No.
Use UrlHelper (Url property in controllers and views). Extends it with ad-hoc functions for resolving your specific urls, as this blog post do.
For resolving views, stick to MVC conventions as explained in Dorian's answer.
We're currently debating two strategies of localization:
A. Have an XML file for the structure of the business objects with a Localized key to a separate CSV file for the translation.
for eg. /Resources/Schema.xml
in a separate CSV file: we have all key/value pairs for the translations:
/Resources/Localized.txt
Model_Title, Title, Title (in French), ...
This way, when the structure changes, we just change XML once while the LocalizedKey's are in place.
B. Have separate XML files for each language based on Culture.
eg. have two files:
/Resources/en-US/US-Localized.xml
/Resources/fr-AU/AU-Localized.xml
This way, they will have same schema but separate files. Therefore the user would have to make sure that the schemas are the same as they would need to change it twice as opposed to Option #1 where they can just change it once.
However, the readability here is much better since the user would not have to track the key the make the changes.
What are your thoughts/ideas on the strategies I suggested?
Thanks,
It is not clear about the environment -- web? desktop? internal enterprise integrated something-or-other? Is there any particular reason you aren't using whatever i18n framework your tool chain supports (gettext, .NET resource files...)?
In general I'd say you want to separate out resources by culture (but to be honsest, fr_AU should be rare) to have better maintainability and do not have to load the entire file for all per-culture-versions in many situations. This is especially true if your number of supported languages/cultures goes into the dozens or more.
However, it would be important to accommodate XML schema changes. The XML could be auto-generated, from simpler structures (key-value, either in a database or files) and validated via a common schema.
This is whether (as commenters noted) you are providing localized products or customers can create their own localizations.
In general, you should consider existing tools, rather than start from the scratch.
In .net we are using Data Driven ASP.NET Localization
Resource Provider and Editor Created by rick strahl
ASP.NET MVC is heavily convention-based, "convention over configuration" as they say. So, this means there's a lot of significance to what name things are given and where in the project structure they are created.
As a newcomer to ASP.NET MVC, I appreciate the power and simplicity of this approach, but I do find it a bit confusing to keep track of what conventions are in play. For example, when using UpdateModel controller method, that relies on HTML form fields having the same names as the properties of the model class. That's the obvious thing to do and most of the time it's probably what most people would do instinctively, but I can see that it would get really confusing if one were to rename something in one place and forget to rename it in the other. The linkage is somewhat 'brittle'.
So, I thought it would be useful to have a list of all the ASP.NET MVC conventions here in one place, as short statements of best practice. things like:
"HTML Form fields should have the same name as Model Properties".
Anyone have anything like that? Will you help me create a list here?
Use the virtual path from your deployment server and enter it in the project configuration in Visual Studio. This way the visual studio development server will use the same path structure as the deployment server. This will save you countless hours of work when deploying.
Controllers should always end with the Controller sufix.
Note that convention over configuration is not required, but is how things work out-of-the-box. If you find a convention confusing or not helpful you can change it (eg. how controllers are picked, how views are located, etc.), or do configuration.
Controller and action names specified in routes should have corresponding classes and action methods named exactly this way (plus "-Controller" suffix for controllers). You can override this behavior using [ControllerName] and [ActionName] attributes.
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.
I am (as I'm sure many of you are) pretty familiar with Rails' MVC design pattern as well as Django (and others') MTV design patter. I was wondering what other patterns other frameworks use for web application development. What are their strengths/weaknesses?
thanks
My miniature (60-line) MVC engine for PHP, http://code.google.com/p/barebonesmvc-php/, used successfully on an embedded consumer device by Cisco, relies on the "template method" pattern, wherein the parent class specifies the steps to an algorithm but the child class is responsible for implementing some of those steps.
static function sendResponse(IBareBonesController $controller) {
$controller->setMto($controller->applyRequestToModel());
$controller->mto->applyModelToView();
}
In the case of my engine, the developer needs to implement applyRequestToModel. Not only Spring's Web/MVC module, but also my applyModelToView method, takes a map/hash/assoc-array and makes it available to the view, except Spring conflates the two facets of MVC in the name of their abstraction (ModelAndView), whereas my abstraction is more appropriately name ModelTransferObject (aka $mto).
Speaking of Spring, in the GoF reference regarding the template method pattern, the GoF refer to "inversion of control"
MTV is just a more accurate name for what's usually called MVC. So in fact, Rails and Django use the same pattern. Is has established over years and hardly any framework does things differently, except maybe the half-object pattern. However, halb-objects have not established in the web world.
The "real" MVC is a pattern found in classical GUIs as well as within JavaScript (if you only look at what's happening within the browser). It is simply not applicable in the WWW so it had to be adapted. The result is confusingly often also called MVC, while MTV is a more accurate description.