Reputation: 24063
I am writing big application for specific customers. The application include many abilities but not all the customers need all the abilities so after a lot of thinking I decided to divide parts of the application to modules, where module is a independent part. I am now in the beginning of the module creation from my old code. Since this is web application, each customer have his own user name and password. I should load only his modules - only his modules should be available to him. In addition, I have two different abilities that can be interact, and sometimes if one customer have both the abilities - I would like to expose "combined web page" and not a web page for a specific ability, so in which module this "combined web page" should be? I havent manage to define what module include. Doess module include its own db tables? Does module include its own web pages? Does module has its own library project? and so on..
Is there anyone who can make sקnse or make order in all the module division? I am really lost here and I don't know how to continue with it.
I am using asp.NET with c# and webservices, jQuery and SQL Server 2005.
Upvotes: 2
Views: 478
Reputation: 42246
It sounds like you mean by modules are sections of a website as opposed to sections of a business model. If you are open to using ASP.NET MVC, they provide a very useful convention for this kind of separation. It is known as "Areas". Give a look to http://msdn.microsoft.com/en-us/library/ee671793.aspx which is a walk through and sample project. In addition there is an introductory video at http://www.asp.net/mvc/videos/aspnet-mvc-2-areas. I think you could accomplish all that you want with the use of MVC areas and ActionFilters that select the role requirements of each action.
Upvotes: 1
Reputation: 101150
What you are looking for is called multi-tenant solutions and it's nothing new. There are several different solutions available.
First of all: Get used to that all modules are loaded at the same time for everyone. Anything else is impossible unless you want to start juggling with appdomains. And that can get nasty real quick.
What you do is simply to control which links and such to display for the user and to validate all requests so that the user have permissions to do what he tries to do.
As for permission handling, I'm using the built in one in .Net. I've added a role for each module that the user have access to. In this way I can tag all my methods with [PrincipalPermission(XXXX)]
attribute to control security. Read up on custom IPrincipal
and IIdentity
.
Next thing to solve is the code layout. I got one class library per module. And in that module I have all layers (repository, models, services, views). Everything is marked internal
except those classes that should be exposed to the rest of the system.
You need something to tie everything together and this is the trickiest part. You need to think long and hard about which interfaces to create to be able to let modules interact with each other.
I do recommend that you use a Inversion Of Control container (my favorite is autofac) and Asp.NET MVC since both gives you some flexibility and makes it easier to build such system.
Upvotes: 2
Reputation: 3021
It is very difficult to say how to design modules since it is specific to your application domain and architectural factors.
You can define modules at various levels of your application and module design can be considered as independent of any specific language. Keep in mind that too much re-use (coupling) can have negative impact as changes ripple through your application if you do not draw specific boundaries. One good defense is to design anticipating change. Thus, it will impact your whole architecture!
“Independent parts” are good, but you need to define the “level” in your architecture: You can have functional modules, “technical” modules (infrastructure code), runtime modules, and even deployment modules. Each type important in a large application.
From the pieces in your question (and not knowing what your domain is about) here are some suggestions:
Note: It really depends on your domain: For example you can have one application supporting multiple users and they are only separated based on the roles (Customer, Employee, Gold Customer..) that they have. For some you might even have separate web services but they can all use a "web presentation/application" service just for a user interface.
Upvotes: 2
Reputation: 6742
This isn't the most sophisticated solution, but this is how I do it-
each user is represented by a User object, which has a AvailableModules property, or possibly a HasModule(module) function.
A centralized repository holds the object that represents the currently logged-on user, and whomever needs can inquire it.
For example- presentation layer would have
if (UsersRepository.CurrentUser.HasModule(Module.Admin))
{
labelAdmin.visible = true;
//other presentation stuff here
}
service layer would have:
public void Do AdminStuff()
{
if (!UsersRepository.CurrentUser.HasModule(Module.Admin))
{
throw new UnauthorizedAccessException("User isn't an admin");
}
//do your admin stuff
}
and so on.
note that you can use that to seperate operations to different classes. for instance-
public interface ISomeService
{
public void DoService(();
}
and the calling code can have-
ISomeService service = new ViewerService();
if (UsersRepository.CurrentUser.HasModule(Module.Admin))
{
service = new AdminService();
}
Upvotes: 0
Reputation: 14209
I think the authorization management in ASP.NET should allow you to do what you need: as explained on this link, you can manage authorizations by page or, as in your case, folder. For instance if you want only users from Group1 to access Folder1, users from Group2 to access Folder2, and both to access Folder3, your Web.config should look like:
<configuration>
....
<!-- Normal config here //-->
<system.web>
....
</system.web>
<!-- Page-specific settings for folder1 here //-->
<location path="folder1">
<system.web>
<authorization>
<allow users="Group1" />
</authorization>
</system.web>
</location>
<!-- Page-specific settings for folder2 here //-->
<location path="folder2">
<system.web>
<authorization>
<allow users="Group2" />
</authorization>
</system.web>
</location>
<!-- Page-specific settings for folder3 here //-->
<location path="folder3">
<system.web>
<authorization>
<allow users="Group1, Group2" />
</authorization>
</system.web>
</location>
</configuration>
Upvotes: 0