I am trying to build a new MVC Project. The thought is I will have a parent domain, and I will be hosting multiple sub products at different sub domains.
[ For Users it will be totally different products.. like: life.insurance.com and general.insurance.com].. and it is also possible that two different teams work on these two child products and they may have different Release Date.
Main thing is, I want to change my Web Project Layer. The Domain Layer, DAL Layer, etc will be common. I was searching for some best Industry Practices in MVC.
Thoughts that I have in Mind:
Create different MVC Areas in Web Project. But what if I want to send product A code to Production but not the Product 2 Code. [How to Resolve this]
Use different Web Projects and change the dll only at Production.
Please suggest. or any New way to handle this scenario?
Under Main Project solution, Create Separate MVC projects for each of the subdomains.
You can create multiple projects for DAL, DomainLayer, Crosscutting, DTOs, UI, Test etc. You can extend it as much as you need and you can find many sample architectures in different complexities. Considering your specific questions, you can route requests using Area as you pointed. In addition, you can implement Areas in different projects which enable you extend your solution without modifying the web project. However; you need to take into consideration that once you add DLL references to your web project, you cannot directly change specific DLLs without rebuilding the whole web project. In order to achive that, you need to resolve your plugin assemblies in runtime. So, you can use Assembly.Load that will help you load specific DLLs anytime you wish.
Related
I am working on a massive ERP on student lifecycle management.
My platform is ASP.NET Web Forms.
Originally, I created my project using the N-tier format, where I had separate tiers for the data access, business logic, and the view.
I had to create different types of view based on different stakeholders, and so my project had different folders to hold the views of a particular stakeholder.
I had folders to hold my data access and business logic as well.
Overall, my project structure was like this:
Project
--BusinessLogic
--class files
--DataAccess
--class files
--Student
--html pages
--Principal
--html pages
--AccountsDept
--html pages
--Teacher
--html pages
--LoginSystem
--html pages
Now, I want to breakdown this structure, because I want to host my student and teacher portals on different servers. But the student and teacher portal will use the same data access layer and the same business logic layer, so I want to make any code changes to these layers from one single page.
I am thinking of this structure
Project 1
--BusinessLogic
--dll files
--DataAccess
--dll files
Student Portal
--Student
--html pages
--LoginSystem
--html pages
Teacher Portal
--Teacher
--html pages
--LoginSystem
--html pages
My view related projects will reference the dlls created from publishing Project 1.
Previously, when I published my single project, I saw that all my c# class files compiled into a single dll files. I think it is possible to reference this dll file in my view related project.
The problem is that, I have a intuition / hunch that this might be possible. But I am not even sure. I do not know whether this is the right way or not.
I am also not wanting to use multiple projects inside a single solution. I want to keep everything separate.
You can think of DLLs like plugins, which can be used across any compatible application as references(this is what you see under References section of your project anyway). The great thing is that DLL can be created by anyone - either Microsoft, third-party company or even yourself, there is no limitations.
Reusing your own components is completely fine and I strongly encourage you to do this. Just remember that if you have some layers, which you want to separate, create additional project as Class Library. Of course it is possible to reference DLLs created as a result of building your web project, but this can cause either errors or unexpected application behavior, since Class Library is designed in a way that it only exposes its interface, without triggering any application life cycle events.
I just ran into a problem with my project. I have my MVC website where my ViewModels live, in second proejct i have BuisnessLogic(services) where i have all my funcky logic going on before it gets from db to the view or the other way arround.
Before, i had my ViewModels outside of the web project together with my services, but now after i moved them inside the webproject my services are crashing, because my services used to return ViewModels and they no longer can get them because of the circular dependency, since website need to get service methods, and services need viewmodels. So basicly i am confused right now, and cant figure out which way to go.
Should i just move Services up into website project together with ViewModels? Or have i misunderstood the purpose of the services in MVC? Or maybe there are some other way to keep serivces separated from web project?
There is no official documented way or standard best practice for this. It is up to you. Some people like that about MVC others think it creates unorganized code. Just maintain 3 tier architecture and you can't go wrong.
MVC + 3 tier; where ViewModels come into play?
What architecture and patterns can I use to share the most model and logic code between a WPF and an ASP.NET MVC application?
I am trying to achieve a bit more here than just separating my data entities from the two presentation projects. There is a lot more in common e.g. UI logic on what gets displayed under what conditions, when is something required, etc. that I would like to keep in the shared code.
ADDED: I am just beginning to really like the concept of view models independent of my entity model driving my presentation. While some of the annotations used in these are located in assemblies specific to MVC, none of the metadata provided is actually web specific. I would very much like to explore using my MVC view models as data sources for binding to WPF views. Any suggestions on this front will be most appreciated.
My personal favorite configuration is similar to the one Adam King suggested above but I like to keep the logic DLL as part of the web project. I run a project called CT Terminal that follows this pattern. My Terminal.Domain project contains all the application logic and simply returns a CommandResult object with properties that act as instructions to tell the UI project what to do. The UI is completely dumb and only processes what it's told to by the Domain project.
Now, following Adam King's approach I would then slap that Domain DLL into a WPF app and then code the UI to follow the instructions in my returned CommandResult object. However, I prefer a different approach. I wrote the MVC 3 UI to expose a JSON API. This API can be consumed by any application. The JSON API was simple because it was basically a wrapper around my Terminal.Domain project CommandResult object. The JSON returned would have the same basic properties. In this way I would write the WPF app to consume this API rather than the DLL. Now if I make minor changes to internal application logic I just deploy the Web project to the live server. All clients using the API automatically get this new logic.
Obviously if the changes being made affect the properties being returned from the API then that would require a release of new client code, but at least for internal logic you wouldn't have to do that.
One of the most widely used patterns seems to be having the Entities in a seperate DLL assembly, then having this referenced from each of the other projects.
MVC 3 suits the repository pattern very nicely, which can be a clean route to take in the first instance, and will work for both WPF and ASP.net
I actually found Rocky Lhotka's books, software, and videos on this topic very helpful. Here's a few links to his content:
http://www.lhotka.net/
http://channel9.msdn.com/Events/Speakers/Rockford-Lhotka
http://www.amazon.com/Expert-C-2008-Business-Objects/dp/1430210192/ref=sr_1_2?s=books&ie=UTF8&qid=1331834548&sr=1-2
Create a service layer for your application by specifying interfaces with methods that represent all of the operations you need to perform. Also, in this service layer, define all of the data types used by the application. Those data type classes should contain only properties, not operations. Put these interfaces and classes in an assembly all by itself. This assembly should be shared between your web app, WPF app, and the code that implements it.
Finally once you have this separation, you can freely develop the application's internal structure, and leave the responsibility of UI operations (e.g. what happens when you click xyz button) to the respective UI.
As an aside, you can expose your service layer, via WCF and web services. You can use this to make call from the web browser via javascript. You could do things like client-side validation or even look up values on the fly for drop down population. all while reusing it between your two application.
Starting with the obvious. Encapsulate your business logic and domain model in a separate assembly.
In terms of Presentation Layers and shared UI Behaviour, the closest you will get is the MVVM design paradigm, implementation will be C# in WPF/XAML and Javascript for your ASP.NET MVC web frontend.
For the web frontend you can get close to the WPF (MVVM) way of doing things with http://knockoutjs.com/ written by Steve Sanderson of Microsoft. Its MVVM for the browser. Also checkout http://www.asp.net/mvc/mvc4 for more info.
Use Web Api, let both the WPF and the Web application consume the services from Web Api.
Done.
Did you try using Portable class libraries. With this you can make the data layer and use it in ASP.Net MVC, WPF, Windows Phone, Silverlight.
I always run into a problem where my projects in Visual Studio (2008) become huge monstrosities and everything is generally thrown into a Web Application project. I know from checking out some open source stuff that they tend to have multiple projects within a solution, each with their own responsibilities.
Does anyone have any advice for how to refactor this out? What should be in a separate project vs. part of the web project? Can you point me to any reference materials on the subject, or is it just something you become accustomed to with time?
Organize your project cleanly into namespaces. Namespaces should not be too big, not too small. Make each namespace have a public "interface" (i.e. a set of public classes) and don't access internal implementation details of the namespace from other namespaces. Different namespaces usually address different parts of an application, e.g. you'll have namespaces related to UI, business logic, helper functionality, etc. The Framework Design Guidelines have some good suggestions how to design namespaces.
When you feel that your project grows too large, simply identify sets of namespaces that are clearly related to each other and move them to separate projects. Since other namespaces already just use the public interface of the moved namespaces, refactoring the namespaces into new projects is merely a file-move-operation.
Start from the bottom up (your simplest classes that don't depend on anything else besides the Framework) and see if you can isolate the dependencies into functional units. For instance, if you have a bunch of data or business logic classes that reference each other, but never reference any of your UI classes, then you have a candidate for splitting off into another project. If you can't find clear separation points, then you have a design problem and should probably do some refactoring.
I also agree that using namespaces is a good place to start. Even within a project, you can often isolate or minimize dependencies in a way that naturally groups classes together. Putting them in the same folder reinforces this grouping as a functional unit and may really help the poor guy who has to maintain your code in the future. Trust me, I try to think about that poor guy because, on more than one occasion, that poor guy has been me. Twas a small comfort that the person who wrote the code had the same name as me at the time that he wrote it.
Check out the guidance given by the Sharp Architecture project. Its ASP.Net MVC but the same principles apply to ASP.NET and other projects. The guys that put this stuff together are smart I generally use their advice as the default and only stray when I have a good reason.
The basic tiering that they propose is
A core project for your domain objects and interfaces for accessing external services (including persistence).
A data project that depends on core and implements all the interfaces for accessing persistence
An application services project for supporting application-level concerns such as logging or login validation. This only references core.
A web project that holds only views.
A controllers project that holds your bootstrapping code and the code for coordinating your web layer, domain.
In the case of an asp.net app I like to use the mvp pattern which would basically mean the
Web project holds your WebForms and codebehinds which should contain only the minimum amount of code required to redirect to the presenter. You probably also will need to put your bootstrapping code in there. This is due to an ASP.Net limitation and you should NOT reference any of that stuff from your codebehinds.
Controllers project is replaced by a presenters project. The big difference here is that somehow the presenter has to be instantiated by the WebForm rather than the other way around.
You can also try to check out the ASP.NET MVP project.
I have plenty experience creating ASP.NET Websites in the Visual Studio. But there is an alternative way to do the same thing that is through Web Applications, which have slightly different file structure.
Since I created my first Web Application I couldn't use classes (.cs files) in the App_Code folder anymore, they were not seen by the ASPX and ASHX classes unless were moved to the same file.
It happens that I use the same classes across many files and I don't want to have multiple copies of them. Where do I put those classes? There is any solution without creating another project?
We have been using Web Application project type in VS 2008 for all our projects and put our common classes in AppCode folder instead of App_Code folder. It works absolutely fine, we access our classes across all the pages in the application without any problem at all.
With Web Application Projects you have a lot more freedom. Just create subfolders under your project to hold your classes. For example, you could have a folder named "DAL" to hold the Data Access Layer items.
Optionally, you can create an assembly project and put your classes in there and just reference it from your WAP.
Ultimately the structure is going to boil down to how many classes you will have.
Why do you not want to create another project? This would be the simplest approach as all your classes would be housed in that assembly which you could project-reference in your web application and then have access to everything across the entire project.
I would highly recommend that you consider this approach.
I normally have three projects within a solution. The web app, the web library (base pages etc) and the DAL. This keeps everything clean.
Put them anywhere you want. I tend to keep the little project-specific helper classes and base pages in a /Helpers folder under the web project, but split out DataLayer stuff and general-purpose reusable helpers to their own separate projects.
I use /Shared/Classes for general purpose classes used throughout the site. I like putting the rest of the classes in a Classes folder where they are used such as /blog/Classes/.
-- EDIT--
The answer above was how I stored classes in Web Forms application projects. Now that I am using MVC, I store general purpose classes in /Classes and non-general classes in subfolders under /Classes such as /Classes/Blog. In short, Old_App_Code has been renamed to Classes. This seems like a natural extension to the naming conventions I see Microsoft using in MVC, plus it works with my old Web Forms pages too.
I highly recommend that you put all your classes (domain objects) in a separate project. This way you will be easily able to write test against your business layer (domain objects) and your classes will be portable. Portable means that you can send your DLL to another developer and he/she can easily reuse the classes you developed.