我正面临着我参与的项目的一些体系结构问题。该项目是一个ASP.NET MVC 2应用程序,它依赖于DI,特别是Unity的构造函数注入。应用程序分为几个模块(每个模块是一组组件),将服务公开给其他模块。这些服务在应用程序启动时注册到Unity。没有什么特别的,直到现在。假设我有这个(每个模块都是一个简化的程序集):
ModuleA,ModuleB。
ModuleA使用以下方法公开服务'IServiceA':
IServiceA(Operation1 - Operation2 - Operation3)
来自ModuleB的ServiceB需要来自ModuleA的IServiceA,它通过构造函数注入(具体实现)获取它。然后它使用它。
问题是当ModuleA被取消激活时(我们检查数据库是否在应用程序启动时为当前用户激活了模块),因此serviceA未在Unity中注册。
然后我们在运行时有一个异常,因为unity无法找到IServiceA的注册,并且无法构造ServiceB。这是正常的。
我想知道它有一套模式或最佳实践来处理它。我的第一个问题是摆脱ServiceB的构造函数注入。但后来我应该使用对ServiceA的硬引用,我不喜欢它或使用更糟糕的ServiceLocator。如果ServiceA可用或不可用,我不想检查ModuleB,因为我会检查许多其他服务,并且应该处理纯基础结构的代码。如果serviceA可用或不可用,我希望ServiceB运行相同的代码(不知道是否可能)。我查看了一个网关模式,但不知道这是否可以帮助我。
任何帮助将不胜感激。
谢谢,
答案 0 :(得分:3)
您需要某种默认实施,可以在取消激活ModuleA时接管。 Null Object模式听起来非常合适。
首先使用Unity注册NullServiceA。这将是默认的IServiceA,除非被实际实现覆盖(让我们称之为ConcreteServiceA)。
对于更复杂的实现,您可以将NullServiceA和ConcreteServiceA包装在Composite中,或者可能是另一种形式的Decorator,根据可用性选择其中一种形式。
例如,你可以拥有一个总是使用注入其中的第一个(或最后一个)IServiceA实例的Composite ......或者选择标准可能基于确定模块是否有某种元数据激活或停用(听起来信息本身可以很好地适应假设的IModule界面)。