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.
Related
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 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.
I've got a bit of a complex scenario that I'm stuck on trying to determine a good model for. The basic idea is that I have a business logic layer that is shared by multiple applications that work in the same domain. Certain minor functionality (such as security and available information) differs from one application to another.
I have an application specific class to be used within each application (as provided by a factory). This will ensure that within each application, the only loaded objects are of the type related to the current application.
The problem I've encountered is that if I have a core logic class B inheriting from a core logic class A and an application specific version of A, I need some way to get the application specific version of B to behave both in the ways it was changed for B and the way it was changed for A.
I realize this is a bit of a classic multiple inheritance problem, but I figured I would check here to see if anyone had any ideas for alternate models that would allow both application specific and core shared functionality.
My other alternative at this point is to simply disallow inheritance in any application specific code and require that any common application specific code be written in a shared library used by both non-related application specific leafs.
The end result of this was that inheritance for each application needed to be limited to leafs and anything that is application specific across multiple leafs needed to be broken out to a class that could be contained. Not ideal, but the best that could be done without multiple inheritance.
I've read MEF documentation on Codeplex and I'm trying to figure out how to accomplish my task:
I would like to build an application framework that has standard components that can be used to do some common work (like displaying a list of records from a database). Plugins should be reused many times with different configuration each time. (eg. I have 5 windows in an application where I display record lists, each with different type of entity, different columns, each one should have it's own extension points like for displaying record details that should be satisfied with a different copy of another common plugin).
Is MEF suitable for such a scenario? How should I define contracts? Should I use metadata? Can I define relationships using configuration files?
Yes, you can use MEF. MEF supports NonShared instantiation of objects using the PartCreationPolicy attribute:
[PartCreationPolicy(CreationPolicy.NonShared)]
More information on this here.
Personally I'd do the wiring and configuration after the importing of the component on the target. However I am not sure how generic you want your application to be, if you are making a 'framework' to do certain solutions in I can imagine you want the configuration to be separate. You can go all-over-board and make an ISuperDuperGridConfiguration and import these on the constructor [ImportingConstructor] of your grid plugin. From within your target (where the grids get imported) set the location of the grid to the grid plugin (like main grid, side grid) and use the data stored in ISuperDuperGridConfiguration to further config the grid plugin itself.
However, you can easily go 'too far' with MEF, depending on your goals. We have a completely MEF componentized UI for an application with customized needs for every single customer. Sometimes I have the urge to put single buttons from the ribbon in a MEF extension.
As you can see, depending on your needs, you can and sometimes will go too far.
I don't think you'd need metadata especially in your case, but maybe someone else can share a different opinion on this ;-).
I hope this answers your question, if not please comment so I can highlight more aspects. All in all using MEF has been very positive for us, and we are using it far beyond a 'hello world' so to say. So at least you have that!
I have a large .NET web application. The system has projects for different intentions (e.g. CMS, Forum, eCommerce), and I have noticed a (naive) pattern of calling on another project's class. For example, the ecommerce module needs functionality to generate a file on the fly for products, and I call and reference a method in the CMS to do this, because file handling is really a job for the CMS.
Obviously (and I know why), this is bad design and a case of high coupling.
I know a few ways to handle high coupling, like restructuring the project (although I don't really think this is a robust solution), but what else can I do to reduce high coupling? Any simple tips? Also, it would be good to know why/how they reduce coupling. I use .NET 3.5 and Sql Server 2005 so things like JMS (which I keep coming across in my search for tips on this design issue), are not applicable.
Thanks
BTW,
One of the reasons I ask this is that I have read the previous questions similar to this but usually if a question that has been asked before is asked again, different tips can be learnt as different people reply to the post.
I know of dependency injection/IOC, but I am interested in the small things that can be done to reduce coupling.
How could I choose between using a static class, or an interface-derived class, or the IOC approach when deciding on how to reduce coupling? Also, I could develop a web service which could call a static class - mixing up the approaches in my solution.
The interesting thing is that in my application, I don't want it to be disjointed. So I just have a forum, ecommerce system, and any other module required, but everything has to gel into one site so each module (which is represented as a dedicated project in my Visual Studio solution) needs to know about every other module and work with it. So for example, I might have a module which handles user profiles (working with ASP.NET membership, roles, etc), but this will work with the forum module as a user on the forum will be a registered user on the site (one login throughout), and his or her profile will be coming from the user profile module. This is as opposed to seperate profiles as seen on other sites I've come across).
You should expose web services in those projects who will be needed by other projects. This is kind of the base level idea behind SOA. So, I would just create web services and consume them, which will decouple you quite a bit from how you have it now. Hope this helps.
I'd consider starting by doing an "extract interface" refactoring on the tightly coupled pieces. For example, if using the CMS as a backing store, create an interface that can store things, then create a mediator or adapter class that knows about the CMS, but isolate the logic that knows about the storage mechanism details to just that class.
Then, for testing, you can easily substitute an in-memory store or local-filesystem store that doesn't depend on the CMS being up.
Consider using techniques like dependency injection (See StructureMap, Spring.Net, NInject) to simplify instantiation if a simple factory doesn't give you the flexibility you need.
It sounds like you have a layering problem. Your assemblies should have a single dependency cycle - from least stable to most stable. That allows you to version sensibly. Generally, that cycle would be something like UI (least stable) -> Domain Core (stable) -> Data Access (most stable). You can throw in a Utilities or some infrastructre assemblies along the way, but again - they should be considered more stable than the assemblies dependent on them.
I'd guess your App.ECommerce and App.Cms assemblies are more siblings than layers - so you would not want those to depend on each other, but that doesn't mean you can't reuse functionality. For your particular scenario, you need to push the needed functionality down to a Core or Utilities assembly that both ECommerce and Cms can depend on. If it's a specific implementation that ECommerce provides, then you can push an interface or abstract base class to the Core - and have a higher layer (perhaps IoC container) wire up the concrete Cms.FileCreator class to the ECommerce.IFileCreator dependency.
Get proper abstractions in place as described by others (interfaces, etc). Program against abstractions, not concretions.
Design your classes with Dependency Injection in mind as you have described.
Use an Inversion of Control Container as the mortar between the bricks.
Unity from the Patterns & Practices team complements the Enterprise Library.
Scott Hanselman has a nice List of .NET Inversion of Control Containers.
Well, I don't know anything about .NET, but how about refactoring common code into a separate, underlaying project/layer? Loads of stuff in a web app can be done generically to suit both a CMS, a forum and eCommerce, writing to a file is a perfect example.
Another approach could be to see the forum and eCommerce as modules in a CMS, which would also make sense. Then they could safely use specified API:s of the CMS.