Reputation: 472
We are building a very large web site that will consist of a main site with many sub sites. These could typically be implemented in areas, but the development cycle and teams for these sub sites are disparate. We want to be able to deploy only a single sub site without taking an outage for the entire thing. We are trying to determine if there is a good, clean way to have a project for the main site and projects for each sub site.
In this case, the main site has all the core layout and navigation menus. The user experience should be that of a single site. Ideally, the sub site projects could be used just like areas in MVC utilizing the layout pages and other assets from the main site.
While I think this is doable by patching things together on the server, there needs to be a good development and debugging story. Ideally, the main site and a subsite could be loaded into Visual Studio for development. Additionally, it would be nice to be able to do a regular web deploy without duplicating core files in each sub site.
Like I mentioned, we could use areas, but would like to know if there are other viable options.
Answers to questions: The sites will probably will reuse some contexts and models. Do they share the actual objects in memory, I don't think so. Each would have their own instances.
There will be several databases partitioned by domain. One for the core site and several more, as many as one per sub site. For example sub site A might need to access some data from sub-site B. This would be handled via a data or service layer.
The site URLs would ideally be as follows: Core site: http://host Sub site A: http://host/a Sub site B: http://host/b
Specific things to share: _layout files, css, js, TypeScript, images, bower packages, etc. Maybe authentication, config, etc.
The authorize attribute would be the preferred approach. A unified security infrastructure that behaved like a single site would be the best option. Not sure if that is possible.
Upvotes: 3
Views: 1657
Reputation: 609
You need an IIS website configured in your dev machine. You can automatize its creation with VS Tasks. You can have also a task to build and publish your solution there as well. This will take some time, but you'll have the advantage it could be reused in your CD/CI build server, with proper configuration.
After creating your main web project in your solution, create a subsite as a new web MVC project, naming it in a way that makes sense. For example, if your main web project is called MySite.Web.Main, Your subsite could be MySite.Web.MySubsite.
Delete global.asax and web.config from all your subsites, and there you go. Once published, all your subsites will rely on the main site global.asax and web.config. If you need to add configuration changes to your main web.config from your subsites, rely on web.config transformation tasks to be triggered after the build complete successfully. You can have different transform files for different environments.
Remember that you'll need to add all that automation to your CI/CD build server as well.
NOTE: when you add a new nuget dependency on your subsite projects, there is a chance it'll create a new web config. It's crucial that all subsite web.configs are either deleted or modified in a way that their "Build Action" property is set to "none", or it'll override the main web config during the publication process. One way to work around this is, instead of deleting the subsite web.config, you delete its content and set "Build Action" to "none" as soon as you create the project.
Upvotes: 0
Reputation: 6011
This seems like a good architecture question. I wouldn’t know how to properly answer your question since I’m no architect and also because it seems to raise more questions than answers...
Assuming a typical layered application looks somewhat like this:
For now, I’m disregarding the fact that you want this in asp.net 5/MVC 6.
Contoso.Core:
This layer would hold your entities/pocos
in addition to anything else that may be used in the other layers. For example, that could be Enums
, Extension methods
, Interfaces
, DTOs
, Helpers
, etc...
Contoso.Data:
This layer would be where you’d store your DbContext
(if you’re using EntityFramework) and all the DbSets<>
, it would also hold the implementation of your repositories (while the interfaces could be living in the Contoso.Core
layer...you’ll see why later).
This layer has a dependency on Contoso.Core
Contoso.Service:
This layer would be your Service layer where you define your services and all the business rules. The methods in this layer would be returning Entities/Pocos or DTOs. The Services would invoke the database thru the repositories assuming you use the Repository Design Pattern.
This layer has a dependency on Contoso.Core
(for the entities/pocos/dtos and for the Interfaces of the repositories since I assume you’ll be injecting them). In addition, you’d also have a dependency on the Contoso.Data
layer where the implementation of your repositories lives.
Contoso.Web.Framework:
This layer would have a dependency on Contoso.Core
, Contoso.Data
and Contoso.Service
.
This layer is where you’d configure your IoC Container
(Autofac, Unity, etc…) since it can see all the Interfaces and their implementation.
In addition, you can think of this layer as “This is where I configure stuff that my web application will use/might use”.
Since that layer is for the web layer, you could place stuff that is relevant to the web such as custom Html Extensions, Helpers, Attribute, etc...
If tomorrow you have a second web application Contoso.Web2
, all you’d need to do from Contoso.Web2
is to add a reference to Contoso.Web.Framework
and you’d be able to use the custom Html Extensions, Helpers, Attributes, etc...
Contoso.Web:
This layer is your UI/client layer.
This layer has a dependency on Contoso.Core
(for the entities/pocos/dtos). It also has a dependency on Contoso.Services
since the Controllers would invoke the Service Layer which in turn would return entities/pocos/dtos. You’d also have a dependency on the Contoso.Web.Framework
since this is where your custom html extensions lives and more importantly, where your IoC container
is configured.
Notice how this layer does not have a dependency on Contoso.Data
layer. That’s because it doesn’t need it. You’re passing by the Service Layer.
For the record, you could even replace the Contoso.Service
Layer by a WebAPI (Contoso.API
) for example allowing you to create different types of applications (winform, console, mobile, etc...) all invoking that Contoso.API
layer.
In short...this is a typical layered architecture you often see in the MVC world.
So what about your question regarding the multiple sub sites? Where would it fit in all of this?
That’s where the many questions come in...
Will those sub sites have their own DbContext or share the same one as the Main site?
Will those sub sites have their own database or the same one as the Main site? Or even different scheme name?
Will those sub sites have their own URL since you seem to want the ability to deploy them independently?
What about things that is common to all those sub sites?
What about security, Authorize Attribute and many more things?
Perhaps the approach of Areas and keeping everything in one website might be less error prone.
Or what about looking at NopCommerce and using the plugin approach? Would that be an alternative?
Not sure I’ve helped in any way but I’d be curious to see how others would tackle this.
Upvotes: 1