我目前正在创建一个小型的个人windows(桌面). net LOB应用程序,我想利用这个机会增加我在DI方面的知识和经验。我已经将我的应用程序分为模型、DAO和GUI部分,但我想知道如何实现一些横切概念,如:
- 当前登录用户-用于:
- 断言权限—在应用程序的某些部分,我检查用户是否具有必要的权限
- 审计—将用户操作记录到单独的数据库表 等
- 当前应用程序参数(从配置文件或表中加载)-用于:
- 定义业务策略
- 定义UI(例如主题) 等
- 记录到文件/数据库日志-用于:
- 记录UI动作(点击按钮等)
- 记录业务流程(计算结果、策略决策等)
- 日志基础设施的东西(SQL用于CRUD操作) 等
目前我可以想到几种方法来提供这些信息:
- 使用静态属性- UserEntity。目前,配置。目前,记录器。目前,等等。
- 优点:
- 实现简单
- 使用简单
- 缺点:
- 一团糟的时候,
- 不清楚应用程序的哪个部分使用了什么
- 不能使用,如果你需要更细的粒度(例如,如果对于应用程序中的某些进程,你需要覆盖当前值)
- 优点:
- 使用DI给每个需要这些信息的类一个属性/参数
- 优点:
- 每个班级都清楚自己需要什么
很容易进行单元测试
- 优点:
- 缺点:
- 它似乎爆炸了构造器
- 如果类需要有默认构造函数 会产生问题
- 当类被第三方实例化(XAML)时难以设置
- 优点:
- 易于设置 使用方便
- 不清楚应用程序的哪个部分使用了什么
- 难以设置更细的粒度(但并非不可能)
我目前倾向于ServiceLocator,因为我以前用过它,它工作得很好。然而,我担心失去控制。这样就很容易找到服务定位器,而不是试图解决设计问题。
谁能提供他们的经验/知识?听起来很适合从面向方面的方法开始。您的应用程序LOB将根据业务功能需求来设计,这些业务功能需求与不同的非功能需求交叉:身份验证、审计、日志记录等。
同时,一些当前的应用需求可以通过依赖注入来解决。首先,我建议首先识别组合根。例如,在wpf应用程序中,它是Application.OnStartup
方法。如果您能够识别组合根,那么最好避免使用服务定位器。服务定位器将在维护和测试时增加不必要的复杂性,因为它可以解决任何问题,因此依赖关系管理将变得复杂。
下一步,要决定:依赖注入和面向方面的方法是分开还是合并。两种方法各有优缺点。
当选择分隔的方法时,你可以使用postsharp,它有很多好处:很好的示例和文档、社区和准备使用的方面。但是没有什么是免费的,postsharp在免费版本中只有有限的功能,并且与持续集成的集成很复杂。
另一个解决方案:将依赖注入与动态代理结合起来。只要你遵循这个概念:面向接口编程,而不是面向实现编程——你就能实现所有的需求。优点:在一个地方连接所有组件。有两个主要的缺点:第一,动态代理本身非常有限,第二,依赖注入容器和动态代理之间的集成——对于某些容器来说它已经存在,对于其他容器来说它还没有。示例:对象扩展拦截,或者StructureMap和拦截。
我建议你看看下面的资源,自己找到更多的答案:* Matthew D. Groves所著的《。net中的AOP:实用面向方面编程》一书:第一章免费提供* Mark Seemann写的。net中的依赖注入:关于依赖注入的书写得很好,第9章专门讨论拦截,我发现这种方法在您所描述的问题中非常有用。这本书的作者还有一个关于依赖注入的优秀博客和关于面向方面的使用依赖注入进行编程的视频