【问题标题】:How to inject dependencies in WCF when the Composition Root is on the client当组合根位于客户端时如何在 WCF 中注入依赖项
【发布时间】:2011-11-26 14:33:15
【问题描述】:

在我开始之前,我必须说我可能咬得比我能咀嚼的多,但我正处于绝望的学习狂潮中,我需要很多帮助。

我正在编写一个练习,从两本书中抽取样本:
1. .Net 中的依赖注入,作者:Mark Seemann
2. Brian Egan 和 Steve Valenzuela 的专业 ASP .Net 设计模式

练习使用 WCF 作为服务层实现请求/响应消息传递模式AND 使用来自客户端应用程序中的组合根的依赖注入。

从 2 开始:
在练习中,对于服务层,我有五个类库:
- 合同:带有服务合同的接口。
- 数据契约:所有用 DataContractAttribute
装饰的对象 - HttpHost:WCF 服务的主机。此库包含所有 svc 文件
- ServiceProxy:此库手动实现服务的代理以供客户端使用
- 服务:包含服务的实现。

从 1:
我想用控制台和 ASP .Net MVC 客户端测试这个练习,因此组合根是第一个的 Main 方法和 Global.asax 和第二个的自定义控制器工厂组合。

所以我的问题是:

  1. 如果组合根是在客户端上实现的,我是否必须为 WCF 中的 ServiceHostFactory、ServiceHost 和 IInstanceProvider 提供自定义实现?那不是让我有两个作文根源吗?
  2. 如果(希望)我只需要客户端中的组合根,我应该在哪里创建具有依赖关系的构造函数?在服务的实现中或在服务的代理中还是在两者中?
  3. 应该如何配置对象层次结构?我想首先使用Poor Man's DI,并且一旦运行将Structure Map 合并为IoC 容器。

非常感谢您的帮助。

这是我到目前为止的代码(我不包括服务合同或数据合同):

服务实现:

namespace Exercise.Services
{
    public class PurchaseOrderService : IPurchaseOrderService
    {

        private readonly IPurchaseOrderFacade PurchaseOrderFacade;

        public PurchaseOrderService(IPurchaseOrderFacade purchaseOrderFacade)
        {
            PurchaseOrderFacade = purchaseOrderFacade;
        }

        public PurchaseOrderResponse CreatePurchaseOrder(PurchaseOrderRequest purchaseOrderRequest)
        {
            var purchaseOrder = PurchaseOrderFacade.CreatePurchaseOrder(purchaseOrderRequest.ToPurchaseOrder());

            var purchaseOrderResponse = purchaseOrder.ToPurchaseOrderResponse();
            purchaseOrderResponse.IsSuccessful = true;

            return purchaseOrderResponse;
        }

        public PurchaseOrderResponse UpdateState(PurchaseOrderRequest purchaseOrderRequest)
        {
            var purchaseOrder = PurchaseOrderFacade.UpdateState(purchaseOrderRequest.ToPurchaseOrder());

            var purchaseOrderResponse = purchaseOrder.ToPurchaseOrderResponse();
            purchaseOrderResponse.IsSuccessful = true;

            return purchaseOrderResponse;
        }
    }
}

这是客户端的代理:

namespace Exercise.ServiceProxy
{
    public class PurchaseOrderProxy : ClientBase<IPurchaseOrderService>, IPurchaseOrderService
    {
        public PurchaseOrderResponse CreatePurchaseOrder(PurchaseOrderRequest purchaseOrderRequest)
        {
            return base.Channel.CreatePurchaseOrder(purchaseOrderRequest);
        }

        public PurchaseOrderResponse UpdateState(PurchaseOrderRequest purchaseOrderRequest)
        {
            return base.Channel.UpdateState(purchaseOrderRequest);
        }
    }
}

【问题讨论】:

  • +1 表示面临挑战。你能把标题中的“no”改成“on”吗?
  • @GertArnold:感谢您注意到错字:)
  • 相关:因为谷歌搜索“WCF 组合根”导致这里和有用的答案被埋葬谁知道在哪个页面上:stackoverflow.com/questions/2454850/…

标签: c# wcf dependency-injection structuremap


【解决方案1】:

每个应用程序都有自己的组合根。 WCF 服务本身就是一个应用程序,这意味着它有自己的组合根。

或者让我换种说法,客户不应该决定服务将如何构建其对象图,这很难想象,因为服务将存在于自己的进程中,并且通常位于单独的机器上。

这并不意味着多个应用程序(例如在同一个解决方案中)不能共享 DI 配置的一部分,但客户端和服务的对象图甚至可能几乎没有共同点(它们没有) t 共享大部分相同的代码库)。例如,当您构建使用相同业务层的 WCF 服务和 Windows 服务时,您将看到更多的配置共享。但即使在这种情况下,尽管它们可能共享大部分 DI 配置,但我们仍然会说它们有自己的 Composition Root。

【讨论】:

  • 因此,如果我理解正确,这意味着客户端(例如 MVC 客户端)将拥有一个容器实例,我将配置控制器接收服务代理实例。另一方面,WCF 项目将拥有自己的容器实例,我将在其中配置其余的依赖项,一直到存储库。那是对的吗?我什至不应该考虑尝试将容器注入 WCF。对吗?
  • 我刚刚完成了这样的实现,它实际上看起来非常漂亮。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2020-05-02
  • 2011-01-28
  • 2011-03-01
  • 1970-01-01
  • 2023-03-19
相关资源
最近更新 更多