65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Unity 进行透明的 WCF 通道管理

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.64/5 (5投票s)

2009年8月29日

LGPL3

3分钟阅读

viewsIcon

26555

使用 Unity 进行透明的 WCF 通道管理

引言

通常认为为所有 WCF 服务定义一个单独的 ServiceContract 接口是一种良好的做法。这样做可以将契约与实现解耦。然而,如果我们通过传统方式(例如使用 ChannelFactory 生成代理或使用 ServiceReference 生成的代理)来消费服务契约,就会将服务与 WCF 基础设施耦合在一起。这有什么问题呢?嗯,假设我们有一个服务的本地版本和一个远程实现,其中一个必须使用 WCF 特定的方法(如上述方法)来检索,而另一个可以注册到我们的 DI 容器中并以这种方式检索。但是,本地和远程实现之间共享的代码必须意识到这一点,这会降低可重用性。如果所有服务的检索都以相同的方式进行,不是更好吗?我们确实可以做到这一点,而且没有任何与 WCF 基础设施的耦合。我稍后会解释如何做到,但首先,我们先了解一些背景知识。

背景

我选择以集中方式管理我的服务频道。我通过使用 IChannelManager 实现来做到这一点。您可以在我的一些文章中了解更多关于使用 IChannelManager 实现的信息。特别是,这里这里

这种方法有几个优点,其中最重要的是频道管理器负责缓存频道代理,并在发生故障时重新创建它们。

使用 Unity 的 IStaticFactoryConfiguration 透明地检索代理

熟悉 Unity 的人会知道,要将类型或实例注册到容器,可以定义配置中的关联,也可以在运行时通过调用容器的 RegisterInstanceRegisterType 方法来完成。然而,还有第三种方法:我们可以注册一个工厂方法来执行检索,通过配置 IStaticFactoryConfiguration 来实现。这使 Unity 能够使用 ChannelManagerSingleton 驱动频道代理的生成或检索。

图:通过 Unity 检索服务频道。

首先,我们必须将扩展注册到 Unity。该扩展可以在 Microsoft.Practices.Unity.StaticFactory.dll 程序集中找到,并且应该被您的项目引用。然后,我们像这样将扩展添加到我们的 Unity 容器

Container.AddNewExtension<StaticFactoryExtension>();

然后,我们可以让 Unity 检索 IChannelManager 实例,以便在请求时检索服务代理。

var channelManager = UnitySingleton.Container.Resolve<IChannelManager>();
UnitySingleton.Container.Configure<IStaticFactoryConfiguration>().RegisterFactory<IMyService>(
				container => channelManager.GetChannel<IMyService>());

因此,我们不再需要在代码中检索 IChannelManager 来检索频道代理。我们所需要做的就是像这样直接从 Unity 中获取它

var myService = UnitySingleton.Container.Resolve<IMyService>();

打开频道、测试连接、缓存它等,所有这些都在后台完成!

这种方法有一个缺点。如果,由于某种原因,频道管理器无法检索频道代理,那么 Unity 将引发 ResolutionFailedException,并且故障原因将隐藏为内部异常。因此,我们必须调整我们的代码以应对解析失败,并且不仅依赖于单元测试来发现缺失的类型注册。这篇文章涵盖了单工服务,我仍然需要探索一种优雅的方法来实现与双工服务及其回调实例相同的结果。

结论

我们已经看到,通过使用 Unity,我们可以进一步抽象频道代理的检索。这使我们能够以相同的方式消费服务,无论它们是本地的还是通过 WCF。通过这样做,我们能够实现与位置无关的服务消费,并提高在本地和远程部署场景中共享代码的可重用性。频道管理器和其他好东西的源代码可以在 这里 找到。

© . All rights reserved.