К сожалению, в ASP.NET нет способа внедрить конструктор с помощью веб-сервисов.ASP.NET требует, чтобы вы предоставили конструктор по умолчанию.Конструктор MyService примерно настолько близок к корню композиции, который вы можете получить с помощью этого типа веб-службы, без использования контейнера DI.
В ASP.NET нет ничего необычного в том, чтобы иметь несколько корней композиции.Которые могут быть конструкторами отдельных веб-сервисов и веб-страниц.Если вы используете ASP.NET MVC, то это ControllerFactory, более дружественный к DI.
В вашей реализации важная часть не состоит в том, чтобы перенести построение графа объектов из веб-службы, так как этокорень вашей композиции.Главное, чтобы веб-служба была максимально тонкой, сохраняла большую часть логики в зависимости, чтобы ее можно было протестировать или использовать повторно.Извлечение информации из заголовков HTTP является примером задачи, которую веб-служба может затем передать этой информации в зависимость.
Хорошей книгой для ссылок на шаблоны и методы DI является ЗависимостьИнъекция в .NET от Mark Seemann.
Если в вашем веб-сервисе вместо System.Web.Services.WebService
реализован System.Web.IHttpHandler
, вы можете реализовать свой 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
, поскольку объект веб-службы не инициализируется до тех пор, пока не будет вызвано событие PreRequestHandlerExecute
, то есть последнее событие перед вызовом ProcessRequest
.
ВышеПример работает, если вы хотите иметь уникальный экземпляр для каждого веб-сервиса.Если вы хотите иметь один и тот же экземпляр (жизненный цикл Singleton) MyBusinessService
для каждого запроса веб-службы, вы можете реализовать файл 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;
}
}