What is the best way to structure a VB.NET Windows Forms application so that code can be reused and the application can be extended easily?
I used to create lots of new forms. This lead to lots of repeated code and forms which did similar things.
Now, for forms which do similar jobs, such as view/edit/delete items from a specific database table, I create a form with the required controls, have the form create an instance of a class with parameters such as a collection of the controls and a string containing the database table name. Then the individual controls call functions of the class.
Advanced forms will inherit and extend this basic form class.
Has there already been work done in this area?
Are there books / articles available which discuss the options available on this topic?
I had great success with this Passive Screen pattern.
In my opinion, the big problem of the traditional MVC architecture is that people stuff way too much into the form classes. This increases the amount of manual testing you have to do.
The more automated testing you can do after you compile, the more bugs you will catch at your desk. In a complex application, the side effects from even minor changes occur all too often.
The trick to solving this is making a controller assembly that the form assembly (or EXE) references. Every form has a corresponding class in the assembly. Clicking a button will call ThisForm.ThisButton(<args>) which will then fire objects lower in your framework. Each form implements an interface so that, if the controller class needs additional information from the form, it has a interface to retrieve it.
Then for your unit testing you simulate an operator performing complex operations by implementing dummy classes to fire events and feed information to the controller classes. The controller classes don't know any different as the dummy classes implement all the expected interfaces.
There is an important exception and that is for trivial dialogs. For dialogs that have a few check boxes I feel this organization is overkill. I use the command pattern a lot. So in the assembly where I define the Command objects, I put the SIMPLE dialog associated with that command. How simple a dialog has to be to get this treatment is up to you.
I like to structure my applications as follows.
Utility - This is an assembly that has stuff I use all the time - Math functions, file function, etc.
Objects - This has the specific objects I am using for this application.
UIFramework - This defines all form and controller interfaces.
Commands - This has all the Command objects that manipulate my application objects.
UI - Objects that implement the controller interfaces
EXE - Forms that implement the form interface and calls the controller objects.
You may want to check out a Rocky Lhotka's popular CSLA Framework. It provides a very structured way to implement business objects so you can keep the non-UI code out of your forms. Beyond just separating your business logic though, it provides built in n-level undo, validation, security, data binding support, etc.
The one complaint most commonly directed at CSLA is that it makes test driven development difficult, so that may be something to consider as well.
Something that can help a lot is the use of User Controls. With user controls you can reuse the same UI in different forms. Also, you can have many user controls on one form, so if you have a form with a tabcontrol that has 5 tabs, the content of each tab could be a user control, so instead of having hundreds of controls all mixed up in one form, each user control has its own controls and validation logic, and you end up with just six controls in the form: the tabcontrol and the 5 user controls.
This doesn't help in separating UI code from application logic, but it enables you to have small, structured entities instead of forms with thousands of lines of code.
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.
Just to prefix this question, I've decided to take a look at moving our works old legacy systems (40+ programs from vb6, vba, vb.net to c#.net) into two separate systems using the same DAL (barcoding terminals and one web based system) as I spend most my day fixing crummy or non existant business logic in 15 year old vba programs. I've recently built an entity framework model complete with fluent validation and couldn't be happier with it after using it for a bit.
The small team is familiar with webforms (but not very) but the last few days I've explored MVC Razor. I was loving MVC Framework until I tried to start trying to add more functions onto the same page and then it seemed arbitrarily hard to replicate our a recent system I put in a webform. Before, I would eager load a customer and all it's child entities and then bind that to single page for the customer so they could access everything (which is what they wanted), it works okay and isn't slow. From this single page I could edit all their account details/contacts/emails/phones/jobs.
All the examples I've done and seen in MVC handle a single update, a single edit etc but surely you can't separate out every single action into a new view/page? I can pass a rich model through to the view in MVC, but then its a pain trying to update all the different child entities.
This is probably the exact design that MVC wasn't designed for maybe, which is okay, I'm willing to adapt it if MVC will be a better platform going forward, but how are you meant to handle adding this complexity in? Some methods I've seen:
Lots of partial views? passing child info to them (or the id and lazy loading it)?
I've seen methods that wrap multiple <forms> around everything and handle actions that way.
Separate pretty much every task out
If the solution is more lightweight and easier to maintain I'll go research whatever I need to I just wanted at an earlier stage to see if I'm wasting my time. Any pointers to the correct questions I should be asking would be greatly appreciated.
ASP.NET MVC is neither more or less better equipped to deal with complex pages than any other technology out there.
Certainly, MVC requires more low-level work than a Web Forms app, with no direct binding support, but in most cases this is a good thing and provides much more flexibility in how your page is rendered.
One of the whole ideas of MVC is to give you more control over things, but that control leads to requiring more knowledge and more effort on your part in most non-trivial cases. MVC provides a number of tooling functions to speed up trivial work (like creating standard table based CRUD) but when you have complex models, you will have to do much of the work yourself.
This is not that MVC is "ill suited" for it, but just that control and flexibility has a trade off with more responsibility on your part.
In your case, you simply create a view model with all the fields you want. Then, you create your form to edit those fields. In your controller, you will need to unflatten that view model and create or update the necessary records in the database. It's not difficult, but it's more work than WebForms databinding.
You could look into more advanced tools (commercial) for MVC, such as Telerik's tools, which have developed more of a databinding like interface, but MVC is not a drag-n-drop technology, and requires you to hook things up and write the various logic for what is done.
If you need drag-n-drop, databound functionality, then no.. MVC is not the correct technology. But then WebForms requires you to accept many compromises as well, and ties your hands in many ways.
You could use partial views, however I seldom use them. I prefer to instead use Editor/DisplayTemplates as these take care of naming your form fields correctly, even for collections and complex objects. PartialViews tend to have lots of gotchas if you aren't careful. I pretty much only use them as fancy includes, or when using Ajax.
I'm not sure what you meay by "wrap multiple <forms> around everything`. You cannot nest forms in HTML, it's not legal. If you mean place a form around each row of a table, that isn't valid html either in most cases (it's not legal to put a form in a between the table and the tr).
It would help if you had a specific problem that you could ask about, vague objections don't help us solve your issue.
You can accomplish anything in MVC that you can in WebForms. The difference is MVC will usually require you to write more code as it doesn't really offer you any "controls" to drop on your page.
In WebForms, it's easy to create a master/detail view with a GridView, FormView and then wrap everything in an UpdatePanel for automagical AJAX support.
In MVC, while you do have helpers like the WebGrid and AjaxHelpers extension methods, creating views and/or pages requires more understanding of how things work to get the desired functionality. When I start a new MVC project, here's what I include:
Backbone.js - client-side "ORM" that performs CRUD operations
against RESTful* APIs
Knockout.js - client-side view models and
real-time data-binding for your views
Knockback.js - wraps
Backbone models in Knockout view models
Using these three frameworks, you can quickly create powerful single-page apps using MVC and WebAPI.
I need some suggestions on how to resolve the issue I am having. I have tried several different options but hit limitation after limitation. Here is a brief overview of what is going on...
We have 40 tables that hold configuration data that needed to implement CRUD operations. We must use Telerik MVC Grid and preferably the INLINE editing. We must manage the original state and the changed properties on a single object. That object will later be serialized into the database for later approval.
Instead of making 40 models, 40 views, 120 crud methods(no delete), that will all closely share the same code except the field names. I am trying to create a way to make this generic enough where we can have 40 models (maybe?), 1 view, 3 crud methods.
I am running into limitation in various areas:
WCF doesn't support generics
Telerik grid doesn't support dynamic types
WCF doesn't keep methods and private properties intact
We are using MEF also, so this is a plugin, inside of a plugin.. i know..
Adding methods to the WCF layer is not permitted...
My Idea?
I thought I would try creating a class to hold the state, well call it ManagedState. I originally wanted the table models to inherit from it and I had it linked to track changes but this was not working.
I also have now tried using the ManagedState class separately from the configuration class
and using that strictly to pass back and forth through our WCF service. Then try using that data to create the original type and hydrate it.
Really there is so much that has gone into this I am flustered. I have no particular code to share as this is an overall question of how I would implement it as I am hitting brick walls all over. I can post code in future if I get a good response to attempt another method to implement.
I see this question had a lot of views so I figured I would respond to answer my question.
I pretty much used T4 templates to generate a TelerikGrid HTMLHelper. The Telerik grid code was generated for each type unfortunately but all I had to do was call the helper and pass my type in and it used a case statement to return the correct grid.
I am interested in general approach for building interactive GUI using MVC3.
The idea is to build set of different components that can be integrated (plugged in) into various scenarios.
Each Component MUST have it's own model definition, controller and views.
Component encapsulates not just the view but also behavior through it's controller.
All internal implementation details, model, behavior, etc... must reside inside component,
so that component becomes independent, modular - black box.
This allows component to be changed without breaking anything in context in which component is used.
Context in which component runs must not make any assumptions about internal details of component implementation.
On the other side the component does not make any assumptions about context in which it will be used.
Finally, the component must provide mechanism to "communicate" or "interact" with outside world. Beside internals, component must provide some kind of "external" interface (like parameters, data, functions, events whatever...) which would allow component to be integrated into execution context.
The Context (or scenario) is part which contains components.
Now, the basic challenge for the context is to manage interaction between components.
Real-world Categories component example:
Component displays list of categories and allows user to perform various actions such as sorting, paging and record selection.
Internally, it has it's own model which stores relevant information like current page, sort, selection, etc...
Internally, it implements all required actions (for basic render, for user actions response, etc...) in it's own controller.
Internally, it handles model state persistence in the view and model state restore in it's own controller.
Real-world Products component example:
Component displays list of products and allows user to perform various actions such as sorting, paging and record selection.
Internally, it has it's own model which stores relevant information like current page, sort, selection, etc...
Internally, it implements all required actions (for basic render, for user actions response, etc...) in it's own controller.
Internally, it handles model state persistence in the view and model state restore in it's own controller.
Real-world Dashboard page (context, scenario) example:
Page displays both Categories and Products components.
Products component displays all products for the currently selected category and thus must provide external interface (parameter or something) to receive selected category identifier from the context.
Categories component must provide some kind of external interface so that context can act when selected category changes and provide selected category identifier for the products component.
Technically, communication approach for page updates would mostly go through AJAX but if this is possible without AJAX, it would be even better.
In the case of AJAX, I would like solution which uses server side controller(s) which decides and renders what should be updated on the client (JSON or something).
I would not like solution in the client script (client side "like" controller) which decides what actions to call and what parts of page to update - this as said in previous paragraph must be decided by controller(s) on the server.
Important: It is not necessarily for the components to work when directly called via some route.
How would you generally implement described system?
I think you need to investigate real projects and see, what approach do you need to use. Try following project and u can find many best practices:
Here u can find implementing of security measures, services, auth and many many useful.
Kigg
http://www.nopcommerce.com/downloads.aspx
http://orchard.codeplex.com/
It's hard to say for me how it's should be implemented. Better to code it. But using of Dependecy Injectction of Views, Controllers, Services, and Repositories are must in your case.
Each controller handles a whole user-machine pattern. That is, roughly, each controller is responsible for orchestrating the user-machine interaction for a user-case(the user-machine patterns that are the result of the analysys phase).
Now if you put "standard behaviours" in controllers who will coordinate the user-machine interaction pattern?
This way you will have "components" without something that coordinate their execution.
In web forms you have pages that coordinates the execution of components put in them...but in Mvc thi coordination role is played by the Controllers themselves.
You can do black-boxes composed of Controllers and Views just if each of them is responsible of a whole user-machine interaction pattern. That is a "Big Components" not a small building blocks, as its is the case when you implement a CMS.
The Orchard CMS use a similar approach. However what you call components are actually pre-defined blocks that play the role of whole sections of the websites being built by the user.
It seems to me that you are trying to achieve something which may not be out-of-the-box compatible with the philosophy of web MVC (other implementations of MVC might support it).
However, if you wanted to go to the trouble of writing a framework on top of ASP MVC, I am sure you could achieve what you want. For example, by using Areas, you could achieve a form of encapsulation of your controllers, view models, and views.
To compose different areas for the same master view, you could write the equivalent of a front controller with its own view that took in a view model - that view model would be primed by the front controller to render actions from the different areas.
You might achieve more mileage by using a client framework such as Backbone.js on top of ASP MVC.
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.