Ответ 1
Невозможно вставлять зависимости в метод расширения.
Для ASP.NET MVC-помощников вам нужно будет сделать какое-то место службы - будь вы похоронили, что с какой-то абстракцией зависит от вас.
Я работаю над приложением ASP MVC 3, и я пишу специальный html-помощник. Это ничего особенного или чрезвычайно сложного, но для этого потребуется экземпляр интерфейса из структурной карты. Я знаю, что я могу просто вызвать объект structmaps factory изнутри метода, но поскольку в остальной части приложения используется IoC, а не в местоположении службы, я бы хотел сохранить его таким образом.
Есть ли способ внедрить интерфейсы в методы расширения изнутри и asp net mvc app?
UPDATE
Пример того, что я делаю, может помочь:
public static class ShowUrl
{
public static string ForShow(this UrlHelper url, int showId)
{
var service = ObjectFactory.GetInstance<IPerformanceService>();
var showName = service.GetPerformanceTitle(showId);
return url.Action(MVC.Performance.Details(showId, showName.ToFriendlyUrl()));
}
}
Что используется следующим образом:
<a href='<%= Url.ForShow(1)%>'>
По сути, я пытаюсь создать URL-адрес с slug из идентификатора объекта. Может быть, я просто буду делать это очень глупо.
Невозможно вставлять зависимости в метод расширения.
Для ASP.NET MVC-помощников вам нужно будет сделать какое-то место службы - будь вы похоронили, что с какой-то абстракцией зависит от вас.
Я бы не рекомендовал это делать. Методы расширения обычно лучше всего используются для простых, хорошо известных операций непосредственно с типом. Если ваш метод расширения зависит от наличия экземпляра другого типа, вполне вероятно, что он не должен начинаться с метода расширения.
Рассмотрите возможность создания фактического класса обслуживания, который выполняет эту функцию, и вводя его там, где это необходимо. Если вам действительно нужно это в методе расширения, рассмотрите возможность переноса функций, которые ваш метод расширения требует в другом статическом классе/методе, и избегайте использования какой-либо инъекции или местоположения.
Обмен некоторыми кодами может проливать больше света на вашу конкретную ситуацию.
Вы не должны вызывать структуру структуры непосредственно в вашем методе расширения. Кроме того, вы должны создать тестовую версию, которая принимает аргумент IPerformanceService, как показано ниже:
public static class ShowUrl
{
public static string ForShow(this UrlHelper url, int showId)
{
//Use the MVC DependencyResolver NOT Structuremap directly (DependencyResolver is using structuremap)
return url.ForShow(showId, DependencyResolver.Current.GetService<IPerformanceService>())
}
//For Unit Testing
public static string ForShow(this UrlHelper url, int showId, IPerformanceService performanceService)
{
var showName = performanceService.GetPerformanceTitle(showId);
return url.Action(MVC.Performance.Details(showId, showName.ToFriendlyUrl()));
}
}
Теперь вы можете передать конкретную реализацию IPerformanceService в свой метод unit test.
Assert.Equal("TheUrl", url.ForShow(8, new PerformanceService());
Дополнительная информация о mocking UrlHelper: ASP.NET MVC: Контроллеры тестирования устройств, использующие UrlHelper