我目前正在创建一个小型个人窗口(桌面).NET LOB申请,我想利用这个机会增加我的知识和经验 DI 。我已将我的应用程序分为模型、DAO 和 GUI 部分,但我想知道如何实现一些横切概念,例如:
- 当前登录的用户 - 用于:
- 声明权限 - 在应用程序的某些部分,我检查用户是否拥有必要的权限
- 审核 - 将用户操作记录到单独的数据库表中
- 等等
- 当前应用程序参数(从配置文件或表加载)-用于:
- 制定业务战略
- 定义 UI(例如主题)
- 等等
- 记录到文件/数据库日志 - 用于:
- 记录 UI 操作(点击按钮等)
- 记录业务流程(计算结果、策略决策等)
- 记录基础设施内容(用于 CRUD 操作的 SQL)
- 等等
目前我可以想到几种方法来提供此信息:
- 使用静态属性 - UserEntity.Current、Configuration.Current、Logger.Current 等。
- 优点:
- 易于实现
- 使用简单
- 缺点:
- 变得困惑
- 不清楚应用程序的哪一部分使用什么
- 如果您需要更细的粒度(例如,如果您需要覆盖应用程序中的某些进程的当前值),则无法使用
- 优点:
- 使用DI - 为每个需要此信息的类提供属性/构造函数参数
- 优点:
- 每个类的需求都很明确
- 易于进行单元测试
- 缺点:
- 它似乎只是爆炸了构造函数
- 如果类需要有默认构造函数,就会出现问题
- 第三方 (XAML) 实例化类时难以设置
- 优点:
- 使用ServiceLocator
- 优点:
- 易于设置
- 易于使用
- 缺点:
- 不清楚应用程序的哪一部分使用什么
- 很难设置更细的粒度(但并非不可能)
- 优点:
我目前倾向于 ServiceLocator,因为我以前使用过它,而且效果非常好。但我担心失去控制。只需找到服务定位器而不是尝试解决设计问题就变得非常容易。
有人可以提供他们的经验/知识吗?
最佳答案
听起来像是完美的案例,以 aspect-oriented 开头方法。您的应用程序的 LOB 将根据业务功能需求进行设计,这些需求已与不同的非功能需求交叉:身份验证、审核、日志记录等。
同时,一些当前的应用需求可以通过 dependency-injection 来解决。首先,我建议首先识别 composition root 。例如,在wpf中应用程序是 Application.OnStartup
方法。如果您能够识别组合根,最好避免 service-locator 。 服务定位器会在维护和测试时增加不必要的复杂性,因为它几乎可以解决任何问题,因此依赖关系管理将变得复杂。
下一步,决定:依赖注入(inject)和面向方面的方法应该分开还是组合。两种方法各有利弊。
在选择分离方法时,您可以使用postsharp有很多好处:很棒的示例和文档、社区和随时可用的方面。但没有什么是免费的,postsharp在免费版本中只有有限的功能,并且与continues-integration的集成很复杂。 .
另一个解决方案:组合 dependency-injection与 dynamic-proxy 。只要您遵循概念:针对接口(interface)而不是实现进行编程 - 您将实现所有要求。优点:在一个地方连接所有组件。有两个主要缺点:首先动态代理本身非常有限,其次是依赖注入(inject)容器和动态代理之间的集成对于某些容器来说已经存在,对其他人来说不存在。示例:Ninject extension Interception ,或 StructureMap 和拦截。
我建议您查看以下资源,自己找到更多答案: * 预订 AOP in .NET: Practical Aspect-Oriented Programming by Matthew D. Groves :第一章免费 * 预订 Dependency Injection in .NET by Mark Seemann :关于依赖注入(inject)的写得很好的书,第 9 章专门讨论拦截,我发现这种方法在您所描述的有问题的情况下非常有用。本书作者还有an excellent blog dedicated to dependency injection以及关于 aspect-oriented programming with dependency Injection 的视频.
关于dependency-injection - 将横切概念实现到 LOB/DI 应用程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14090498/