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.
Related
Hi after creating a button in HTML in Visual studio, how can i do its backend c# coding? Normally while using webforms double click will open coding class but how to acheive this in Visual studio for HTML element?
I think you can use the MVC pattern. To be more familiar with, you can read this documentation https://www.asp.net/mvc.
Few words about MVC pattern:
Define MVC in layman’s terms
Remember you’re technically minded and close to the code. MVC to you
is as clear as day, but saying to the business ‘Model, View,
Contoller’ could give them the impression that you are suffering from
some form tourette syndrome. MVC won’t mean much to the business even
after you define them in relation to the code. To get the business to
understand why this is the answer and least of all what it is, can be
more of a task than expected in my experience. Even some fellow
developers have difficulty understanding this on occasion.
To get the listener to understand what MVC is and why it works what I
have tried in the pass is to apply MVC to a different industries where
the listeners have had more involvement. An example that has worked
for me in the past in a comparison to the property or even the
vehicles. Most people have had dealing’s with builders, carpenters,
plumbers, electricians or have watched the flood of property shows on
the TV. This experience is a good platform to use and to explain why
separation such as MVC works. I know you’re probably thinking that
won’t work as it’s not the same as in software, but remember you’re
not trying to train the business to become developers or have an in
depth understanding of MVC, simply explaining to them that separation
in production is required and that’s what an MVC structure offers.
To give an example of how you could describe this I have very briefly
explained how separation works in property. Keep in mind this is
focused on using the system not developing which could be a completely
different angle of explanation.
View
The view in MVC is the presentation layer. This is what the end user
of a product will see and interact with. A system can have multiple
views of all different types ranging from command line output to
rendered HTML. The view doesn’t consist of business logic in most
clear designs. The interface is fit for purpose and is the area of
interaction. Therefore you could simply output HTML for consumers to
interact with or output SOAP/XML for businesses to interact with. Both
use the same business logic behind the system otherwise known as the
models and controllers.
In the world of property you could think of the view as the interior
of a property or the outer layer of a property that the inhabitants
interact with. The interior can be customised for purpose and the same
property can have many different types of tenants. For example a
property of a particular design could contain residential dwellings.
The same internal space could easily be used as office space, where
although in the same property has a different purpose. However the
property structure is the same. Therefore the environment in which the
users interact does not interfere with the structure of the building.
Controllers
The controller is where the magic happens and defines the business
application logic. This could be where the user has sent a response
from the view, then this response is used to process the internal
workings of the request and processes the response back to the user.
Taking a typical response where a user has requested to buy a book.
The controller has the user id, payment details, shipping address and
item choice. These elements are then processed through the business
logic to complete a purchase. The data is passed through the system
into the model layer and eventually after the entire request satisfies
the business definitions, the order is constructed and the user
receives their item.
If we compare this to a property, we could compare the ordering of a
book online to turning on a light switch. A tenant will flick the
switch to on just like ordering a book. The switch itself is an
element in the view layer which sends the request to the controller
just like clicking a checkout button on a web site. The business logic
in this case is what the electrician installed and are embedded within
the property designs. The switch is flicked, which completes the
circuit. Electricity runs through all the wires including the fuse box
straight through to the light bulb. Just like the user receiving a
book, in this case the tenant receives light. The whole process behind
the scenes involving the electricity cabling is not visible to the the
tenant. They simply interact with the switch within the space and from
there the controller handles the request.
Models
The models in MVC are the bottom most layer and handle the core logic
of the system. In most cases this could be seen as the layer that
interacts with the data source. In systems using MVC, the controller
will pass information to the model in order to store and retrieve
data. Following on from the example above controller definition, this
is where the order details are stored. Additional data such as stock
levels, physical location of product of the book amongst many things
are all stored here. If that was the last book in stock ordered, the
next request for this item may check if it’s available and disallow
the order as the item is no longer available.
Sticking with out example of turning on a light switch, this level in
our structure could be the electricity supply. When the tenant flicks
the switch, the internal circuit must request electricity to power the
request which is similar when the user requested data from the
database, as in data is needed to process a request. If the dwelling
isn’t connected to an electric supply, it cannot complete the process.
Business benefits from using MVC
After you get the message across explaining what MVC is, you will then
have to see what benefits can be obtained from it. I’m not going to go
into a huge amount of detail here are I’m sure you can apply benefits
more accurately which are directly related to you actual situation. To
list just some of the common benefits of an MVC based system here are
a few examples:
Different skill levels can work on different system levels. For example designers can work on the interface (View) with very little
development knowledge and developers can work on the business logic
(Controller) with very little concern for the design level. Then they
simply integrate together on completion.
As a result of the above separation projects can be managed easier and quicker. The designer can start the interfaces before the
developer and vice versa. This development process can be parallel as
opposed to being sequential therefore reducing development time.
Easy to have multiple view types using the same business logic.
Clear route through the system. You clearly know where there different levels of the system are. With a clear route of the system,
logic can be shared and improved. This has added security benefits as
you clearly know the permitted route from the data to the user and can
have clear security checks along the route.
Each layer is responsible for itself. (Relates to point 1) This means that you can have clean file structure which can be maintained
and managed much easier and quicker than a tightly couple system where
you may have lots of duplicate logic.
Having a clear structure means development will be more transparent which should result in reduced development time,
maintenance problems and release cycles if applied properly.
Source: http://www.strongandagile.co.uk/index.php/a-really-simple-explanation-of-mvc/
Another option is keep programming using WebForms, for that, you have to choose the right application:
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.
Let's imagine that there is a MVC web application which is going to be consumed by 3 types of users.
User type 1 and type 2 will use their EMAIL address as username to login to system while user type 3 will use only an alpha numeric username to login since they are not old enough to acquire an email address.
All data models will live under a separate library called Business Objects Tier while data access will separated out to data access tier. Main web application will call out business service classes/repository classes to interact with the database and business logic.
Basic layout of the project is similar to following.
Now how am I going to achieve custom authentication for this layout? Can I ever use a one custom authentication system to cater for all three types of users?Could you please direct me to a good example?
OR do you think I should separate out web area into three separate projects for each user type WITHOUT keeping under Areas inside one web project? In that way I can user normal authentication model but then how am I going to publish those three web applications into one single domain name? But I don't mind having three separate branches under one domain name.
www.mycompany.myapp.com/usertypeone
www.mycompany.myapp.com/usertypetwo
www.mycompany.myapp.com/usertypethree
But then how I can deploy those three separate web projects into those three branches? All the custom authentication examples I have seen use simple username and password system but I couldn't find any shows how to use combination of both.
After I posted my question I kept on thinking...
Perhaps I can separate my web area into three separate mvc projects (without having areas under one mvc project) and have 3 different separate authentication systems inside those three separate projects. Then I can publish those three separate projects into three separate subdomains under one single domain.
But I would love to know your expert views on that.
I would stick to the areas approach.
Use a custom AuthorizationFilter. Once registered globally, MVC will let your filter decide whether the request is authorized or not. Your filter can use the Area being accessed to perform that decision.
More info with code here
Hope it helps.
Miquel
I am building a hosted business SaaS application using MVC 4/C# 4. I'd need to have customer specific resource files, css, views, and business logic that leverage a base code layer as much as possible. How would each of these (resource files, css, views, logic) need to be structured to accomplish this?
I realize this is probably a very in depth answer...but I have no idea where to start or what to search for to begin to research this. Any pointers so I can research further?
Here are my initial thoughts on each:
Views
Use a Switch statement based on user to return different views.
CSS
Use switch statement in view to specify which css to load
Resource Files
I'm not using them now but need to implement, so not sure exactly how they work. From what I've seen you can specify a resource file at the class MetaData level, which is a compile time thing. Not sure how you would change this at the user level. I can see here, how to change it based on culture...but not by a user profile attribute (like the company they belong to).
This looks like a start...will review more.
Business Logic
In my services layer, I could implement switch statements...but that seems messy. Is there a way to create a new classes that override the base classes but only for certain users? Or putting these in a separate project/dll and only using that dll reference for a certain user?
I used to work on the IBM iSeries, and they had the concept of a library path that could be set by user at login. You'd have a custom code path that overrode the base code path libraries. Is there anything similar in MVC?
Data Localization
In my database, I have a table for Orders and another for OrderStatuses, which may be displayed in a drop down for the user to select a status. These statuses may be 'Open' and 'Closed'. But another customer may want that in Spanish...How would you handle this?
Any other considerations I am missing?
Use switch statement
Any time someone is writing object-oriented code and mentions a switch statement to control variable requirements, alarm lights begin to flash.
When you have similar but different requirements, polymorphism is your friend.
Without knowing full details of your requirements it is difficult to provide a specific answer, but consider using the factory pattern / dependency injection to provide objects appropriate to a specific user (or more probably, to the company associated with a specific user).
UI Layer
Generally speaking you could use a factory to return controller instances, based on a common subclass, that implement requirements for a specific user/customer and return views appropriate to that user.
I'm not well enough versed in the specifics of wiring routes in ASP.Net MVC to suggest how specifically to set that up, but it feels like the right approach. Perhaps another poster can shed more light.
Business Logic
This is a classic use of polymorphism, when requirements vary significantly. Alternatives to per-customer classes include configuration-driven behavior and rules engines. The best choice depends on your specific sitation.
Data Localization
Things like order status in the DB should not be bound to a text like 'Open'. They should be bound to a binary representation (e.g. an INT). Leave it to the View to translate that meaning into something specific to the user's language.
In a SaaS application we have developed we have clients who have their own private domains so being able to support something like that was a must. We had to be able to support:
www.mycompany.com/u/clientname
clientname.mycompany.com
www.clientname.com
On of the things we considered was how we could use a single deployment/code base to handle all of these clients. What we ended up with was a Base system that could be extended through the use of "plugins" which are basically class libraries named "APP.Clients.{ClientName}".
We wrote a custom ViewEngine that allows us to make use of these plugins to load Views, Controllers and even Controller Actions from the clients custom plugin to over-ride the base site.
What we ended up with is similar to what people call "portable areas" or basically external views and controllers in an Assembly.
Clients can share a common "network" database or they can be rolled off in to their own database. Most all of the config comes from reading the current URL and having logic that can determine which "client" it is and loading their settings and processing their customization.
Being able to load the client views required adding in additional search locations for Master Pages, Views and Partial Views (why we have a custom ViewEngine).
There is no simple answer and what works for one SaaS project may not work exactly the same for another. Your architecture will likely be similar but your business needs will dictate where your project takes you!
I am trying to run multiple sites using single code base and code base consist of the following module (i.e. classes)
User module
Q & A module
Faq module
and each class works on MVC pattern i.e. it consist of
Entity class
Helper class (i.e. static class)
View (i.e. pages and controls)
and let say I have 2 sites site1.com and site2.com. And I am trying to achieve following functionality
site1.com can have User, Q & A and Faq module up and running
site2.com can have User and Q & A module live while Faq module is switched off but it can be turned-on if needed, so my query here is what is the best way to achieve such functionality
do I introduce a flag bit that I check on every page and control belonging to that module? It's more like CMS where you can turn on/off different features. I am trying to get my head around it, please provide me with an example or point out if I am taking the wrong approach.
You might want to look at Portable areas. You could design the code base so that each module is an area and then deploy them into the sites were they are needed.
After looking to some example and an extensive research I come to a conclusion that it depends upon 2 scenarios:
Scenario 1:
If in a case where there is only ten possible modules which are written once and require the whole update of the entire application if they need to be updated, then you can easily use checks which will propagate through the models and be used by the views to adjust the user interface (for example by showing or not the appropriate links in the web application menu).
Scenario 2:
If, instead, there is a case of many modules developed by many developers and it is unacceptable to require the update of the whole web application in order to update any of such modules, then look for plugins model, like for example the one used in FogBugz.
For making choice, consider following elements sorted by importance:
Maintainability: is it acceptable to modify the common code of the web application in order to change any of the modules?
Dependencies: are some modules dependent of others?
Performance: since we don't know the exact context, it's difficult to try to predict the impact of each solution. Maybe there will be
none, if you use heavy, cleverly designed caching.
Overall architecture: if there are reasons to do something monolithic (because of the interdependencies), the first solution
seems more appropriate; this is not the case if every module is
strictly separated from others.