开发者

Multiple ASP.NET web applications depending on a common base application

开发者 https://www.devze.com 2023-03-22 13:53 出处:网络
I have multiple SQL Server databases (same schema) for different customers. They will be sharing a common ASP.NET web application. If one of these customers wants a customized version of a web page, w

I have multiple SQL Server databases (same schema) for different customers. They will be sharing a common ASP.NET web application. If one of these customers wants a customized version of a web page, we will create a new one in his directory (or project).

Example:

/Main Application/WebPage.aspx
/Ma开发者_运维知识库in Application/WebPage2.aspx

/Main Application/Customer 1/WebPage.aspx

/Main Application/Customer 2/WebPage.aspx

At the moment, I have the following project structure

Solution (Main application)

    ASP.NET Main Project
    Other projects (BLL, DAL, etc.)

Solution (Customer 1)
    ASP.NET Project
    Other projects (BLL, DAL, etc.)

Same thing for Customer 2

In each customer solution, I added a reference to the main application project to resolve the dependencies and also to use the web pages that are not customized.

Each ASP.NET project represents a different IIS virtual directory, so we have 3 for this example. (/Main, /Main/Customer1, /Main/Customer2).

The problem I have now is when I try to connect to the right database. Each ASP.NET project inside of each solution have a web.config file with the customer's database connection string. When I run a program (let's say WebPage2.aspx) from the base ASP.NET project (Main Application), I cannot get this connection string so I don't know what database to connect to.

I have tried to put all my connection strings in the main application web.config, but I cannot find a way to reference the right one when the project starts. There doesn't seem to be a way to set a custom property where I can specify the current solution's connection string name (or key) at the solution level.

Any ideas or toughts on this? I don't mind changing my project structure, but it is important that every customer has it's own solution so we can keep this clean and separated.


I would, if I were you, consider creating a NuGet package from your main application base. (NuGet packages can be kept entirely private, so you don't have to worry about open source requirements...)

With a NuGet package, you can copy dll assemblies, aspx files, xml configuration and virtually anything else each customer needs to have, just by installing the package into the customer's solution. You can create a separate virtual directory (or even web site) in IIS for each customer, and they will all have everything they need to run.

On top of that, you gain another very important thing by doing it this way: maintainability. You can keep working on new features and bug fixes in your main solution, and whenever you want to push something to the customer sites, you just publish an update to the NuGet package. Then you can install that package update into one or all of your customer specific sites, but you won't have to do it at the same time. If one customer site needs to lag behind for some reason, it doesn't stop the other customers from getting access to new features.

Creating a NuGet package is easy, and it will take you to maintainability heaven compared to a solution where multiple sites in separate solutions depend on builds from yet another solution, where you can't even check all your code at the same time for compile errors...


One path you could take is to deploy all of the sites into the same directory.

You could do something like:

Library - These are Class Library projects
Library.Core <- classes common to all modules
Customer.Cust1 <- classes just for customer #1
Customer.Cust2 <- classes just for customer #2

Sites - All web sites
Site.Core <- main site, has your web.config and common pages
Site.Cust1 <- contains items specific to this customer. References Customer.Cust1 and Library.Core Site.Cust2 <- specific to customer 2. References Customer.Cust2 and Library.Core

The Customer sites should be structured like:

$Project Name  
    / Styles
        cust1.css
    / Scripts
        cust1.js
    /Customer 1 
       / Cust1page.aspx (whatever you want to call it)
       / Cust2page.aspx 

The main site should be structured like:

$Project Name
    / Styles
        main.css
    / Scripts
        main.js
    / whatever common directory
       whateverpage.aspx
    / master
       masterpage.master

You can make a copy of the masterpage.master and place it into each customer site. Just set it to do not copy and content type none.

When you deploy, do the main site first. After that deploy the customer sites. Do NOT let the deployment delete files first.

.Net will happily combine everything. As long as you don't have any name collisions you'll be good to go.

This will let you deploy a single customer or all of them into the same machine.

Next, don't store the customer specific connection strings in the web.config. Instead, just store a connection string to resolve logins in a common database. When a person logs in, have the DB give you the connection string to use for the rest of the site.

Optionally, you could combine the databases into just one and use schema's to separate table names on a customer basis. for example cust1.Accounting or whatever.


Sounds to me like you should have completely separate solutions for each client, complete with all the code it needs to run, instead of relying on a base web application. You can have a DLL that contains all of your base functionality (base pages, data access rules, etc.) which is shared among all of your solutions (maybe individual copies, maybe in the GAC), but I probably wouldn't use a base web application - I don't know if that's even possible.


There doesn't seem to be a way to set a custom property where I can specify the current solution's connection string name (or key) at the solution level.

You're not going to be able to do this via the solution, you need to use an assembly.

My suggestion would be to define a nice small interface (say "IClientIDKey"), which is ultimately consumed by the central shared logic / factory that established client specific data access.

For each client generate a unique ClientIDKey project that implements the IClientIDKey

The problem I have now is when I try to connect to the right database

So this would be solved by the IClientIDKey. You need to let the app start, and pass some sort of variable into a factory that establishes the correct DB connection. I diodn think this variable could be a URL or a login, but after re-reading your question and thinking about it I think the IClientIDKey will do it all for you. For this initial stage you'd be hitting a shared central DB. Once the correct DB is identified you then know where to route all client specific requests.

Which leads to the next part:

interface. When you deploy you only need to deploy the clients key DLL, which is loaded at runtime.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号