在普通的ASP.NET MVC页面中,存储库被传递到控件的构造函数中。然后测试可以实例化控制器并传入模拟存储库。
那么我该如何在Web服务中实现这一点呢?我看到的问题是我们没有ControllerBuilder.SetControllerFactory的等效物。
有什么最佳实践方法可以让我的IoC框架(Castle)使用正确的存储库实现来实例化我的Web服务?
我认为可能有一种方法是扩展HttpHandler并更改Web服务实际实例化的方式。我相信这就是MVC框架的实现方式。
在普通的ASP.NET MVC页面中,存储库被传递到控件的构造函数中。然后测试可以实例化控制器并传入模拟存储库。
那么我该如何在Web服务中实现这一点呢?我看到的问题是我们没有ControllerBuilder.SetControllerFactory的等效物。
有什么最佳实践方法可以让我的IoC框架(Castle)使用正确的存储库实现来实例化我的Web服务?
我认为可能有一种方法是扩展HttpHandler并更改Web服务实际实例化的方式。我相信这就是MVC框架的实现方式。
ObjectFactory.BuildUp(this);
这是一个反模式。由DI容器初始化的类不应该知道DI容器本身。但我还没有找到更好的解决方案。
我相信你正在寻找Castle Windsor WCF Integration Facility。它提供了一个ServiceHost实现,接管您的服务实现的构建过程,利用Windsor IOC。您可以像使用任何其他IoC应用程序一样使用此工具注入依赖项,并且方便的是,它是Castle项目的一部分:
http://www.castleproject.org/container/facilities/trunk/wcf/index.html
如果Castle Project版本不能满足您的需求,我有自己创建的工具可以在发现Castle项目版本之前为Windsor执行相同的操作。它们通常都会执行相同的操作,但是两者处理问题的方式略有不同。你有没有什么理由不能创建一个带有所需构造函数的自定义类,然后在asmx中实例化该类的对象,然后将所有操作委托给该对象?
我通常会像这样创建这些类型的对象:
var o = CustomClass.Create();
public class CustomClass
{
public static CustomClass Create()
{
return IoC.Resolve<CustomClass>();
}
}
public static class IoC
{
public T Resolve<T>()
{
return yourStaticReferenceToPreferredContainer.Resolve<T>();
}
}
定义一个基类并在其中使用属性注入。Pete已经说过了,但你要做的是:ObjectFactory.BuildUp(this);
不同之处在于,我会将其放在Web服务的基类中,这样对于特定的实现就是“自动的”。
这样只需要一行代码,所以除非你有在运行时切换DI容器的明确需求(不太可能),否则不需要关心它。如果你仍然需要这个功能,只需将调用移动到一个单独的类中,并在那里使用特定的DI容器即可。