Sharing / Extending Controllers in large ASP.net MVC application - c#

I'm developing a fairly large application.
It's basically an eCommerce app- with other "features" like Forums etc...
The "back office" app will be called "Wokingham"
What I currently have is something like this:
(we have a naming convention bases on names of trees)
MyCompany.Honeysuckle
Project that contains the Model and Data Access (IRepository etc..) for forums
MyCompany.Willow
Models and data access for Products, product search etc...
MyCompany.Poplar
Models / data access / services etc.. for Orders
MyCompany.Juniper
Customers
All the above are class libraries, that compile into a common /bin/ dir
Wokingham (the admin backend system, mentioned above) will share some functionality with the "public" web app-
For example- in Forums (MyCompany.Honeysuckle) - the public app will have the ability to add a new Question.
This functionality is also available in Wokingham.
My question is when it comes to Controllers of the MVC applications.
There will be (at least) 2 ASP.NET MVC Applications-
A separate one for "Wokingham"
Should I have a MyCompany.Honeysuckle.Controllers project? That both the public UI project and Wokingham share.?
Or-
Should there be the MyCompany.Honeysuckle.Controllers mentioned above, but then the .Wokingham project extends the controllers to perform additional required functionality?

I would separate the two controllers, one for front-end operations and one for admin side. The tricky question is where to put the shared operations.
The short way: can you just redirect/open new window if an admin user wants to create a new forum post? This would save you lot of time, and is common practice.
The long way: if having two pages doing the same thing is necessary, then I would go with separate controller operations and views, but shared CRUD services (model layer). The work is mainly to create the different view.
Generally speaking, you want to keep controller operations as simple as possible, as they are just end-point to web requests. And going through the trouble to abstract similarities between two slightly different controller operations is overkill.
Edit: removed irrelevant suggestions.

Related

MVC project - two sites same controllers

I have a dilemma how to organise my new project.
At the moment, I have a magazine style website coded in MVC C# where every page has an own controller with a set of views. Behind controllers, we have a service layer (as a separate project) for accessing to database. Majority of the business logic is in service layer with some bits of the business logic in controllers
We're planning to launch a new website which is going to use a copy of the 1st site database, with 95% the same features as the first website but completely different views/css.
We have a really tight deadline and we want to reuse as much as possible of the existing code and to make both sites super easy to maintain.
As far as I can see we have two options:
To create a new project for the 2nd website, where we will need to re-write all controllers from scratch
To add a new set of views to the existing website and based on a configuration switch to show different views based on the url of the 1st or 2nd site.
1st approach is much cleaner but at also it will generate loads of repeated code and probably a maintenance nightmare.
2nd approach will use the same controllers (with potentially doubled methods for 5% of different functionalities).
Is there 3rd of doing this?
thanks
At the end I decided to implement custom views via DisplayMode
DisplayModeProvider.Instance.Modes.Insert(0, new NewSiteDisplayMode()
{
ContextCondition = context => IshkaDisplayMode.IsNewSite(context.Request)
});
Now if I need a custom view for the new website I just create a copy of the existing view add NewSite into name and put specific HTML inside.
Cheers
I would use approach 2 if the changes to the business logic are minor and if you can keep it compatible.
There is in fact a third approach, which would be to create a source control branch for v2. You can keep maintaining v1 and integrate the changes to v2 when necessary. Over time however, as your sites drift, these integrations are going to become harder. This approach would thus only be suitable if you have a definite cutoff to get rid of v1.
Depending on the changes to the data model you may need to be able to version your data access code also.
James,
You can use software branching, trunk based development.
Your 2nd approach is smart, where you only have to create new views and rest of your website including business logic, server validations will work like charm.
Infact that is the pure essence of MVC development.

Separate projects for MVC5 and Web API 2

I am new to MVC and Web API. I created two separate projects. One ASP.NET MVC 5 (MyUI) and other ASP.NET Web API 2 (MyApi). I would like to keep my API project separate from my UI layer.
The AccountController class in MVC project (MyUI) is essentially doing the same that the AccountController in the API project does (MyApi). I first thought about making the MyUI.AccountController a sub class of MyApi.AccountController but then I quickly realize that first inherits from Controller and second from ApiController type.
So my questions are:
In order to remove data access logic from MVC 5 project, should I
just convert the AccountController to a wrapper class which will
essentially call the corresponding methods from the
MyApi.AccountController?
Is there a better approach?
Edit:
Edit 2:
While trying to articulate the problem I realized that I was going about it incorrectly. My confusion came from the ASP.NET Identity implementations which were embedded within the API project. That needs to be moved to the Data Access layer and both controllers need to access them the same way which is a whole different can of worms :)
Thanks!!
Method 1 seems a plausible solution but what I would suggest is to create a new class library and there put your data logic. In that way, the MVC project and the Web Api project could connect to that class library.
The reason is that you never know if you write another UI layer, Service layer or other connectivity layer. All those layers could then connect to the same data logic layer.
Extract the common implementation into a separate project (a class library for instance). Your business logic must be the same no matter how you access it. After all, the web service and the site are only a view of the same information and the same control logic. In the future you might be required to write a fat client in WPF or a service in WCF and you do not want to rewrite everything, do you?
I think you are asking about layering application. basically the choice depends on requirements.If you are following data centric design check this layering
Research about DI,ORM,Repository Pattern, SOLID Principlese

multi tenant or multi instance application on intranet

I have an existing MVC app which will be utlized by another user group in the near future. Both the existing and new user group/program will have independant data. I was just thinking to add flags in the tables to distinguish between the two user group/programs and do some routing when they access the application to pull up respective data.
Now when it comes to code customization, for instance one group/program wants to have extra fields on a page which the first group does not want or the process flow of the application is seperate between the two user groups.
If the above two scenarios will occur frequently, should I just do a new web and database instance rather than customizing the code for each program/user group. This way both of my customers/user groups will have flexibility to add different logic/fields to the application.
The only con I see with the non-multi tenant approach is the time effort by the developer to maintain two seperate applications. I am scared of adding contional logic to customize the same code base for each different user group/program. Cost of infrastructure is not an issue. Also I do not forsee this application to be used by more than 2 user groups/programs at any time. So what do you guys think which apporach i should take and why? thanks all in advance
P.S The users arent any ninjas who will try to hack the site to see the other tenants data. They are corporate users. Theyd rather not use this application but its part of the process so they have to use it.
It's worth taking a look at microsoft's article on multi-tenancy.
I'm also working on trying to design an mvc app with such an architecture where each client can have separate fields and customised screens.
The conclusion that I have come to is that using an IOC container with multi-tenancy support will probably make the whole thing a lot easier.
Autofac has built in multi-tenancy support.
In terms of having logic for clients in each view I believe that if you go down the IOC path you can have a controller for each tenant and in that case hard coding such client specific logic isn't necessarily as bad as it would be having it hard coded all into a shared controller. In essence I believe when writing a component that is for a particular tenant you can switch you mindset to writing as if that tenant was the only one using the system.
The other solution I have landed in for customising views is to use a variation of the RazorGenerator approach for compiled views where I have each tenants views compiled into a separate assembly and have created my own view engine (based on this) where I can swap out the assembly that I look for views in depending on a value in the routing parameters.
Of course I'm still exploring this approach and haven't fully flushed it out in order to find out where it may fall short.
If the difference in the 2 users' requirements is more than 10% of the screens/functionality then you better have 2 databases and apps. If it is expected to be less than 10% then just write separate actions (possibly with different prefixes or suffixes in Action names) for where the functionality differs.

Grouping Views, Controllers, Models in MVC

maybe i am wrong but i seriously i don't like the current structure of MVC application, and i think on big projects it will cause trouble to maintain.
so is there a way to group related Controllers,Views, Models together, like if i have gallery Module i want all it's Controllers, Views, Models to be grouped under Gallery Folder.
Areas sound like what you are looking for. This will let you group controllers/views/etc. Unless I misunderstood the question?
Phil Haack discussed this here, it's the same issue I've faced and have yet to overcome correctly.
From the sound of it you're moving against the basic principals of MVC, that being the separation of Model, View and Controller rather than your desire to split at 90 degrees to that by using modules.
I'm not entirely sure what benefit you would get from splitting it in to modules any way since I would expect you to have one GalleryController. Where you are likely to have the most 'entities' needing grouping is with the views, possibly one or more for each GalleryController action, but they are in their own folder which gives the sort of functionality you are looking for anyway.
Finally there are the models. Obviously I don't know your project so I don't know how it is laid out, but the Models do not usually exist for the use of one Controller (or module in your case). For example - I have Models for Users, Companies, Vehicles, etc, etc. These models are a shared representation of my data structure and have nothing to do with modules as a user may see it looking at a web page. I can't split them in to modules because the whole point is that they are shared by the entire application.
So...in reality it is the Views which can get a bit messy, but they are already split in to folders based on their Controller. Having said that you can move them around a bit if that suits your needs better. For the rest of it there is no need, either because you shouldn't if you want to use 'proper' MVC (i.e. modular Models) or there's no need (i.e. only one Controller). And if your controller gets too big just create a separate module for any functionality in that you want to split out. I reckon that's as modular as you should ever need to get.
I found a relatively simple solution that uses IIS configuration to simulate areas. No extensions to the existing MVC framework are needed.
Create a new MVC project under your solution for each area you want in your site (ex. Root, Blog, Forum, App1, App2). If you need any common supporting code or a common model, put it in a seperate dll project that the MVC projects depend on.
In IIS, configure the site root to point at the root project directory. Create web applications under the site root that point to each of the sub-area project directories.
When configuring the route maps for each sub area, don't include the name of the application in the route. IIS seems to take care of this for you. (ex. "ShowPost/{postname}", not "/Blog/ShowPost/{postname}")
The benefit is that you can change the name of the web applications independent of the routing system, and each application believes it is running with the whole server to itself.

Can I use the NerdDinner sample project as a base template for a larger project?

I'm new to the MVC framework and have just run through the NerdDinner sample project. I'm loving this approach over form-based asp.net.
I'd like to spin of a more sizable side project using this same approach. Do you see anything in that project that would prevent me from enlarging the basic structure to a more complex website?
Examples of things that make me wary:
1) The NerdDinner sample accesses a db of only two tables, my db has around 30.
2) The NerdDinner project uses the LinqToSQL classes directly... all the way from the model, through the controller, to the view... is that kosher for a larger project?
Do you see any other parts of the NerdDinner framework that might cause me future grief?
I agree with others that the model should be the only place you use linq2sql and my little addendum to that is only use linq2sql in models in small projects. For larger sites it might be worth the overhead to create a separate Web Service project that does all the talking to the database and utilize the web service in your Model.
I never fully checked out the Nerd Diner example but other best practices include Typed Views and using a datamodeler that allows for easy validation (see xval or the DataAnnotations model binder). To me these are 2 of the most important best practices/
Stephen Walter has alot of excellent tips on his website that are worth checking out and taking into account when setting up a new MVC project.
I would add a service layer between the repositories and controllers. The service layer will contain all of your business logic leaving your controllers to deal mainly with processing form inputs and page flow.
Within the repositories I map LinqToSql classes and fields to domain models and then use the domain models within the service layer, controllers and views. For a larger system the extra layers will prove their worth in the long run.
There's alot of debate around the internet when it comes to the Linq to Sql classes. Some feel that it's not enough abstraction when you use the classes directly, and some feel that that's what they're there for. At work we starting revamping our site, and we're using MVC. The way we decided to go was basically each one of the LINQ to SQL classes implements an interface. IE:
public partial class LinqToSqlClass //generated class
{
public int Id{get;set;}
}
interface ILinqToSqlClass
{
int Id{get;set;}
}
public partial class LinqToSqlClass : ILinqToSqlClass
{
}
This is just a very small part of it. We then have a repository that gets you any of these generated class, but only as that of their interface type. This way, we're never actually working directly with the Linq to Sql classes. There are many many different ways to do this, but generally I would say yes, if you're dealing with a large database (especially if the schema may change) or if you're dealing with data that may come from more than one source, definitely don't use the classes directly.
Bottom line is, there's alot of good info in that Nerd Dinner chapter, but when creating your own project, you'll obviously run into issues of your own so take it as you go.
The Nerd Dinner text makes the claim that the MVC framework can equally well accommodate other common data abstractions. (It's true.) It sounds like your organization already has one it likes. A good learning strategy would probably be to adapt one to the other.

Categories