我有一个.NET 2.0 Web服务的服务引用。我在我的存储库中引用了这个服务,我想转移到Ninject。我一直在使用DI已经有一段时间了,但还没有尝试过像这样的网络服务。
因此,在我的代码中,存储库构造函数创建了两个对象:服务的客户端代理,以及作为代理中每个方法的第一个参数的AuthHeader对象。
AuthHeader是我有摩擦的地方。因为需要具体类型作为代理中每次调用的第一个参数,我相信我需要依赖我的存储库中的AuthHeader。这是真的吗?
我从reference.cs中提取了AuthHeader的接口。我想转到我的存储库构造函数的以下内容:
[Inject]
public PackageRepository(IWebService service, IAuthHeader authHeader)
{
_service = service;
_authHeader = authHeader;
}
...但是我无法调用我的服务代理,如
_service.MakeSomeCall(_authheader, "some value").
...因为MakeSomeCall需要一个AuthHeader,而不是IAuthHeader。
我在这里找个圆孔吗?这只是一个没有自然契合的区域(因为网络服务“很棒”)?我错过了一种方法吗?
答案 0 :(得分:1)
很难准确理解这里的问题,但一些一般性的建议可能与这种情况有关:
依赖注入并不意味着一切都必须是一个接口。我不确定为什么要尝试从WSDL生成的Web服务代理中提取接口; WSDL中的类型是您必须遵循的合同。如果IAuthHeader
没有任何行为(它似乎没有)并且您将永远不会有其他实现,这尤其愚蠢。
这看起来完全错误的原因是因为 错误;这个网络服务设计很差。所有消息(如身份验证令牌)共有的信息不应该放在正文中,而是转换为方法参数;相反,它应该在消息 header 中,其中具有讽刺意义的AuthHeader
明确不是。在执行任何操作之前,可以在客户端或服务端拦截标头并检查标头。在WCF中,这是行为的一部分(通常用于身份验证的ClientCredentials
),在传统的WSE中,它是作为扩展完成的。虽然理论上可以使用消息体中的信息来实现这一点,但是可靠地实现这一点要困难得多。
无论如何,这里真正重要的不是您的存储库所依赖的,而是依赖于 的依赖。如果你的AuthHeader
被内核注入为依赖关系,那么你仍然可以获得DI的所有好处 - 特别是能够将这些全部注册到一个地方或替换不同的实现(即派生类)
除了设计问题之外,我认为您的DI实施中没有真正的问题。如果班级需要AuthHeader
,则注入AuthHeader
。不要担心确切的语法和类型,只要它将该依赖关系作为构造函数参数或属性。