模块划分——如何正确划分?如何分离现有的能力?

发布于 2024-10-23 13:40:40 字数 428 浏览 1 评论 0原文

我正在为特定客户编写大型应用程序。 该应用程序包含很多功能,但并非所有客户都需要所有功能,因此经过深思熟虑,我决定将应用程序的各个部分划分为模块,其中模块是一个独立的部分。 我现在正开始从旧代码创建模块。 由于这是 Web 应用程序,因此每个客户都有自己的用户名和密码。我应该只加载他的模块 - 只有他的模块应该可供他使用。 此外,我有两种可以交互的不同能力,有时如果一个客户同时具备这两种能力 - 我想公开“组合网页”而不是特定能力的网页,那么这个“组合网页”在哪个模块中网页”应该是? 我还没有设法定义包含哪些模块。模块是否包含自己的数据库表?模块是否包含自己的网页?模块有自己的库项目吗?等等..

有没有人可以在所有模块划分中进行理解或排序?我真的迷失在这里,我不知道如何继续下去。

我将 asp.NET 与 c# 和 webservices、jQuery 和 SQL Server 2005 一起使用。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

会傲 2024-10-30 13:40:40

很难说如何设计模块,因为它特定于您的应用程序领域和架构因素。

您可以在应用程序的各个级别定义模块,并且模块设计可以被视为独立于任何特定语言。请记住,如果您不划定特定的界限,过多的重用(耦合)可能会产生负面影响,因为更改会波及到您的应用程序。一种好的防御方法是设计预期变化。因此,它将影响您的整个架构

“独立部分”很好,但你需要定义架构中的“级别”:你可以有功能模块、“技术”模块(基础设施代码)、运行时模块,甚至部署模块。每种类型在大型应用程序中都很重要。

从您问题中的各个部分(并且不知道您的域是什么)来看,这里有一些建议:

  • 通过为 Web 服务提供自己的数据库来隔离它。 (独立)。
  • 让 Web 服务调用其他 Web 服务(封装/组合)
  • 在代码、文件或数据库中使用配置(每个客户、每个 Web 服务)来为客户加载功能模块。 (请参阅依赖注入作为解决配置问题的良好模式。)
  • 使用域/业务需求作为您的 Web 服务和模块的指南。
  • 查看领域驱动设计,特别是有界上下文。其中有很多模式可以为您提供有关如何模块化应用程序的想法。
  • 预测变化(不要太深)并尝试围绕它设计您的架构(技术和功能)。
  • 将您的应用程序分解为重用基础设施(技术)模块的功能模块。分层隔离。

注意:这实际上取决于您的域:例如,您可以拥有一个支持多个用户的应用程序,并且它们仅根据角色(客户、员工、黄金客户。 .) 他们有。对于某些人来说,您甚至可能拥有单独的 Web 服务,但它们都可以仅针对用户界面使用“Web 演示/应用程序”服务。

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:

  • Isolate a web service by giving it it's own database. (independence).
  • Let web services call other web services (encapsulation/composition)
  • Use a configuration (per customer, per web service) in code, file or db to load functional modules for a customer. (See Dependency Injection as a good pattern that works with configuration issues.)
  • Use the domain/business requirements as guides for your web service and modules.
  • Take a look at Domain Driven Design and specifically the Bounded Context. There are lots of patterns there that will give you ideas on how to modularize your application.
  • Anticipate change (not too deep) and try to design your architecture around that (Technical and functional).
  • Break your application into functional modules that re-use infrastructure (technical) modules. Isolate with layers.

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.

晨与橙与城 2024-10-30 13:40:40

您正在寻找的称为多租户解决方案,这并不是什么新鲜事。有几种不同的解决方案可用。

首先:习惯每个人同时加载所有模块。除非你想开始处理应用程序域,否则任何其他事情都是不可能的。这很快就会变得令人讨厌。

您所做的只是控制向用户显示哪些链接等,并验证所有请求,以便用户有权执行他尝试执行的操作。

至于权限处理,我正在使用.Net 中内置的权限处理。我为用户有权访问的每个模块添加了一个角色。通过这种方式,我可以使用 [PrincipalPermission(XXXX)] 属性标记所有方法来控制安全性。阅读自定义 IPrincipalIIdentity

接下来要解决的是代码布局。我每个模块都有一个类库。在该模块中,我拥有所有层(存储库、模型、服务、视图)。除了那些应该暴露给系统其余部分的类之外,所有内容都被标记为内部

你需要一些东西将所有东西连接在一起,这是最棘手的部分。您需要仔细思考要创建哪些接口才能让模块相互交互。

我确实建议您使用控制反转容器(我最喜欢的是 autofac)和 Asp.NET MVC,因为两者都为您提供了一定的灵活性,并使构建此类系统变得更容易。

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.

著墨染雨君画夕 2024-10-30 13:40:40

听起来您所说的模块是网站的部分,而不是业务模型的部分。如果您愿意使用 ASP.NET MVC,它们为这种分离提供了非常有用的约定。它被称为“区域”。查看 http://msdn.microsoft.com/en-us/library /ee671793.aspx 这是一个演练和示例项目。此外,还有一个介绍视频 http://www.asp.net /mvc/videos/aspnet-mvc-2-areas。我认为您可以通过使用 MVC 区域和选择每个操作的角色要求的 ActionFilters 来完成您想要的一切。

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.

流年里的时光 2024-10-30 13:40:40

我认为 ASP.NET 中的授权管理 应该允许您执行以下操作您需要:如此链接所述,您可以按页面或文件夹(如您的情况)管理授权。例如,如果您希望仅Group1中的用户访问Folder1Group2中的用户访问Folder2,并且两者都访问要访问 Folder3,您的 Web.config 应如下所示:

<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>

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>
左耳近心 2024-10-30 13:40:40

这不是最复杂的解决方案,但这就是我的做法-
每个用户都由一个 User 对象表示,该对象具有一个 AvailableModules 属性,或者可能具有一个 HasModule(module) 函数。
集中存储库保存代表当前登录用户的对象,任何需要的人都可以查询它。
例如,表示层将有

if (UsersRepository.CurrentUser.HasModule(Module.Admin))
{
labelAdmin.visible = true;
//other presentation stuff here
}

服务层将有:

public void Do AdminStuff()
{
   if (!UsersRepository.CurrentUser.HasModule(Module.Admin))
   {
     throw new UnauthorizedAccessException("User isn't an admin");
   }
   //do your admin stuff
}

等等。
请注意,您可以使用它来将操作分离到不同的类。例如 -

public interface ISomeService
{
   public void DoService(();
}

并且调用代码可以有 -

ISomeService service = new ViewerService();
if (UsersRepository.CurrentUser.HasModule(Module.Admin))
{
   service = new AdminService();
}

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文