一个例子是:
public class MyService : System.Web.Services.WebService { [WebMethod] public string HelloWorld() { return new MyBusinessService().MyMethod(); } } public class MyBusinessService : IMyBusinessService { public string MyMethod() { return "hello"; } }
我想使用依赖注入来消除对我的服务“新建”的需要,但是我无法想出这样做。我可以让它工作使用可怜的人DI,或至少我认为这被称为“穷人”。
喜欢这个:
public class MyService : System.Web.Services.WebService { private IMyBusinessService _myService; public MyService(IMyBusinessService myService) { _myService = myService; } public MyService() : this(new MyBusinessServie()) { } [WebMethod] public string HelloWorld() { return _myService.MyMethod(); } }
但是我根本无法弄清楚如何使用IoC容器来注入我的依赖项,因为我无法在没有参数的构造函数的情况下运行该服务。
请善良,我不是一个有经验的程序员,刚刚开始测试依赖注入,并使其在我的Windows窗体应用程序工作正常,结构图,但被困在这一个。
使用ASP.NET,具有多个组合根源并不罕见。哪些可以是单个Web服务和网页的构造函数。如果您正在使用ASP.NET MVC,那么ControllerFactory就是更加DI的友好。
随着您的实现,重要的部分是不要从Web服务移动对象图形的构造,因为这是您的组成根。要做的最主要的事情是保持Web服务尽可能的薄,保持大部分逻辑依赖,以便可以测试或重用。从HTTP标头中拉出信息是Web服务可以将该信息传递给依赖关系的任务的示例。
马克·塞曼(Mark Seemann)提供了一本关于DI图案和技术的好书。
如果您的Web服务实现System.Web.IHttpHandler而不是从System.Web.Services.WebService派生,您可以像这样实现您的DI:
Global.ashx.cs
public class Global : HttpApplication { protected void Application_PreRequestHandlerExecute(object sender,EventArgs e) { var context = ((HttpApplication)sender).Context; var needsMyBusinessService = context.Handler as INeedMyBusinessService; if (needsMyBusinessService != null) needsMyBusinessService.MyBusinessService = new MyBusinessService(); } }
MyService.ashx.cs
public class MyService : IHttpHandler,INeedMyBusinessService { public IMyBusinessService MyBusinessService { get; set; } public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { // uses my dependency } }
INeedMyBusinessService.cs
public interface INeedMyBusinessService { IMyBusinessService MyBusinessService { get; set; } }
但是,这种实现的抓住是,对于实现System.Web.Services.WebService的Web服务不起作用,因为在调用PreRequestHandlerExecute事件之前Web服务对象不被初始化,这是调用ProcessRequest之前的最后一个事件。
如果您想为每个Web服务拥有一个唯一的实例,上述示例将会起作用。如果您想为每个Web服务请求提供与MyBusinessService相同的实例(Singleton生命周期),则可以实现Global.ashx.cs文件:
public class Global : HttpApplication { private static IMyBusinessService businessService; protected void Application_Start(object sender,EventArgs e) { Global.businessService = new MyBusinessService(); } protected void Application_PreRequestHandlerExecute(object sender,EventArgs e) { var context = ((HttpApplication)sender).Context; var needsMyBusinessService = context.Handler as INeedMyBusinessService; if (needsMyBusinessService != null) needsMyBusinessService.MyBusinessService = Global.businessService; } }