lim*_*lim 19 dependencies inversion-of-control asmx code-injection
所以我在尝试让我的asmx webservice使用依赖注入和使用IoC来实现时遇到了困难.我希望我的webservice能够使用我的内部业务层服务.Web服务将由来自不同域的外部客户端使用,主要用于发送和接收有关订单和客户等实体的信息.
一个例子是:
public class MyService : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return new MyBusinessService().MyMethod();
}
}
public class MyBusinessService : IMyBusinessService
{
public string MyMethod()
{
return "hello";
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用依赖注入来消除"新"我的服务的需要,但我无法找到一种方法来做到这一点.我可以使用穷人的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();
}
}
Run Code Online (Sandbox Code Playgroud)
但我简直无法理解如何使用IoC容器来注入我的依赖项,因为我无法让服务在没有无参数构造函数的情况下运行.请善待,我不是一个有经验的程序员和刚开始测试的依赖注入,并得到它的工作在我的Windows罚款structuremap形成的应用,但就死在这一个.
JG *_* SD 37
遗憾的是,没有任何方法可以在ASP.NET中使用Web服务执行构造函数注入.ASP.NET提供了一个默认构造函数.MyService的构造函数与使用此类Web服务可以获得的组合根一样接近,而不使用DI容器.
使用ASP.NET,拥有多个组合根并不罕见.哪个可以是各个Web服务和Web页面的构造函数.如果您使用的是ASP.NET MVC,则它是ControllerFactory,它更友好.
对于您的实现,重要的部分不是从Web服务移动对象图的构造,因为这是您的组合根.要做的主要是保持Web服务尽可能薄,将大多数逻辑保留在依赖项中,以便可以对其进行测试或重用.从HTTP标头中提取信息是Web服务可以将该信息传递给依赖关系的任务的示例.
参考DI模式和技术的好书是Mark Seemann 在.NET中的依赖注入.
如果您的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();
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
INeedMyBusinessService.cs
public interface INeedMyBusinessService
{
IMyBusinessService MyBusinessService { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然而与此实施美中不足的是,是不会不与实现Web服务工作System.Web.Services.WebService作为Web服务对象未初始化,直到之后的PreRequestHandlerExecute事件调用,这是最后一个事件之前ProcessRequest被调用.
如果您希望为每个Web服务提供唯一的实例,则上述示例有效.如果您希望MyBusinessService为每个Web服务请求提供相同的实例(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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7986 次 |
| 最近记录: |