将交叉概念实施到LOB / DI应用程序中

时间:2012-12-30 11:55:08

标签: dependency-injection application-design lob

我目前正在创建一个小型个人Windows(桌面).NET LOB应用程序,我希望利用这个机会增加我对DI的知识和经验。我已将我的应用程序分为模型,DAO和GUI部分,但我想知道如何实现一些跨领域的概念,例如:

  • 当前登录用户 - 用于:
    • 断言权利 - 在应用程序的某些部分,我检查用户是否具有必要的权利
    • 审核 - 将用户操作记录到单独的数据库表中
  • 当前应用程序参数(从配置文件或表中加载) - 用于:
    • 定义业务战略
    • 定义UI(例如主题)
  • 记录到文件/数据库日志 - 用于:
    • 记录UI操作(单击按钮等)
    • 记录业务流程(计算结果,策略决策等)
    • 记录基础设施内容(用于CRUD操作的SQL)

目前,我可以想出几种方法来提供这些信息:

  • 使用静态属性 - UserEntity.Current,Configuration.Current,Logger.Current等。
    • 优点:
      • 易于实施
      • 简单易用
    • 缺点:
      • 变得凌乱
      • 目前还不清楚应用程序的哪个部分使用了什么
      • 如果您需要更精细的粒度,则无法使用(例如,对于应用程序中的某些进程,您需要覆盖当前值)
  • 使用DI - 为需要此信息的每个类提供property / ctor参数
    • 优点:
      • 每个班级都清楚它需要什么
      • 易于单元测试
    • 缺点:
      • 它似乎爆炸了构造函数
      • 如果类需要具有默认构造函数,则会出现问题
      • 当第三方(XAML)实例化类时很难设置
  • 使用ServiceLocator
    • 优点:
      • 易于设置
      • 易于使用
    • 缺点:
      • 目前还不清楚应用程序的哪个部分使用了什么
      • 难以设置更精细的粒度(但并非不可能)

我目前正倾向于使用ServiceLocator,因为我以前使用它并且工作得非常好。但是我担心失控。只需触及服务定位器而不是尝试修复设计问题就很容易了。

有人可以提供他们的经验/知识吗?

1 个答案:

答案 0 :(得分:2)

听起来像方法开始的完美案例。您的应用程序的LOB将根据业务功能要求进行设计,这些要求已经被交叉使用,具有不同的非功能性要求:身份验证,审计,日志记录等。

同时,可以解决部分当前应用程序要求。首先,我建议先确定composition root。例如,在应用程序中,它是Application.OnStartup方法。如果您能够识别组合根,最好避免使用服务定位器将在维护和测试时添加不必要的复杂性,因为它可以解决任何问题,因此依赖管理将变得复杂。

下一步,决定:依赖注入面向方面的方法应该分开或组合。这两种方法都有其优点和缺点。

在选择分离方法时,您可以使用并获得很多好处:优秀的示例和文档,社区和随时可用的方面。但没有什么是免费的, postsharp 在免费版本中只有有限数量的功能,并且与进行了复杂的集成。

另一种解决方案:将结合使用。只要您遵循概念:程序到界面,而不是实现 - 您将实现所有要求。优点:一个地方可以连接所有组件。有两个主要缺点:第一个动态代理本身非常有限,第二个 - 依赖注入容器动态代理之间的集成 - 对于某些容器而言已存在,其他人则不存在。示例:Ninject extension Interception,或StructureMap和Interception。

我建议您自己查看以下资源以找到更多答案: *预订AOP in .NET: Practical Aspect-Oriented Programming by Matthew D. Groves:第一章免费提供 *预订Dependency Injection in .NET by Mark Seemann:关于依赖注入的精心编写的书,以及专门用于拦截的第9章,我发现这种方法在你所描述的案例中非常有用。该书的作者还有an excellent blog dedicated to dependency injection和关于aspect-oriented programming with dependency Injection的视频。