3

我在参与的项目中遇到了一些架构问题。该项目是一个 ASP.NET MVC 2 应用程序,它依赖于 DI,尤其是使用 Unity 的构造函数注入。应用程序分为几个模块(每个模块是一组程序集),将服务暴露给其他模块。这些服务在应用程序启动时注册到 Unity。到目前为止没有什么特别的。假设我有这个(每个模块都是一个简化的程序集):

模块A,模块B。

ModuleA 使用以下方法公开服务“IServiceA”:

IServiceA(操作 1 - 操作 2 - 操作 3)

ModuleB 中的 ServiceB 需要 ModuleA 中的 IServiceA ,它通过构造函数注入(具有具体实现)来获取它。然后它使用它。

问题是当 ModuleA 被停用时(如果在应用程序启动时为当前用户激活了模块,我们会在数据库中检查),因此 serviceA 没有在 Unity 中注册。

然后我们在运行时出现异常,因为 unity 找不到 IServiceA 的注册并​​且无法构造 ServiceB。这是正常的。

我想知道有一套模式或最佳实践来处理它。我的第一个想法是摆脱 ServiceB 的构造函数注入。但是我应该使用对 ServiceA 的硬引用,但我不喜欢它,或者使用更糟糕的 ServiceLocator。如果 ServiceA 可用,我不想检查 ModuleB,因为我会检查许多其他服务,并且应该处理纯基础设施的代码。如果 serviceA 可用或不可用,我希望 ServiceB 运行相同的代码(不知道是否可能)。我查看了网关模式,但不知道这是否可以帮助我。

任何帮助将不胜感激。

谢谢,

4

1 回答 1

3

您将需要某种可以在 ModuleA 停用时接管的默认实现。Null Object模式听起来非常合适。

只需先在 Unity 中注册您的 NullServiceA。这将是默认的 IServiceA,除非被实际实现覆盖(我们称之为 ConcreteServiceA)。

对于更复杂的实现,您可以将 NullServiceA 和 ConcreteServiceA 包装在Composite中,或者可能是另一种形式的装饰器,它根据可用性选择一个而不是另一个。

例如,您可以拥有一个始终使用注入其中的第一个(或最后一个)IServiceA 实例的 Composite...已停用(听起来该信息本身可以很好地融入假设的 IModule 界面)。

于 2010-09-13T17:05:59.403 回答