2009-11-10 1 views
4

У меня есть страница ASP.NET, которая реализует мое представление и создает презентатора на странице constuctor. Phil Haack's post providing was used as the starting point, и я просто примеры из сообщения, чтобы проиллюстрировать вопрос.Зависимость службы инъекции ASP.NET MVP

public partial class _Default : System.Web.UI.Page, IPostEditView { 

    PostEditController controller; 
    public _Default() 
    { 
     this.controller = new PostEditController(this, new BlogDataService()); 
    } 
} 

Каков наилучший подход для ввода экземпляра BlogDataService? В примерах, которые я нашел, используются свойства в классе страницы для зависимости, отмеченной атрибутом, который разрешает инфраструктура инъекции.

Однако я предпочитаю использовать подход конструктора для целей тестирования.

У кого-нибудь есть вход или, возможно, ссылки на хорошие реализации вышеизложенного. Я бы предпочел Ninject, но StructureMap или Windsor были бы хороши до тех пор, пока он бегло.

Благодарим за любую отзыв.

ответ

1

Если вы используете Microsoft ServiceLocator, вы можете применить service locator design pattern и спросить контейнер для обслуживания.

В вашем случае это будет выглядеть примерно так:

public partial class _Default : System.Web.UI.Page, IPostEditView { 

    PostEditController controller; 
    public _Default() 
    { 
     var service = ServiceLocator.Current.GetInstance<IBlogDataService>(); 
     this.controller = new PostEditController(this, service); 
    } 
} 

ServiceLocator имеет реализаций для замка Виндзор и StructureMap. Не уверен в Ninject, но тривиально создать адаптер ServiceLocator для нового IoC.

+0

Мне это нравится, спасибо. – blu

+0

Используя этот подход, представление теперь знает об IBlogDataService, который должен был быть известен только ведущему. Есть ли способ построить презентатор, используя контейнер DI, проходящий в текущем объекте представления и настроенный экземпляр IBlogDataService? – Scott

+0

Использование локатора службы считается анти-шаблоном для IoC. Там должен быть лучший путь. –

1

Я не видел метод общего назначения для инжекции конструктора на веб-формах. Я предполагаю, что это возможно с помощью реализации PageFactory, но поскольку большинство на краю прямо сейчас перемещаются в MVC, а не в веб-формы, это может не произойти.

Однако autofac (а DI контейнер мне очень нравится) имеет integration module for ASP.NET WebForms, что делает инъекцию свойства без атрибутов - ваш код будет выглядеть следующим образом:

public partial class _Default : System.Web.UI.Page, IPostEditView { 

    public IBlogDataService DataService{get;set;} 
    public _Default() 
    { 
    } 
} 

Я знаю, что конкретно не решить ваши желания использовать инъекцию конструктора, но это самое близкое, о чем я знаю.

+0

Будет ли контейнер гарантировать, что свойство установлено до вызова вызываемого кода конструктора? Чувствует, что у меня курица и яйцо. – blu

+0

Нет, свойство будет установлено после вызова конструктора. Боюсь, из-за боли в веб-формах. –

+0

В итоге я использовал autofac вместо ServiceLocator, но в стиле Neil выше. Спасибо за это. – blu

2

В нашей домашней структуре MVP у нас был типичный базовый класс, который унаследовал все страницы. Тип, который должен быть типа Presenter (наш базовый класс презентатора)

В базовом классе мы тогда инициализировали контроллер, используя контейнер IoC. Код

Примера:

public class EditPage : BasePage<EditController> { 
} 

public class EditController : Presenter { 
public EditController(IService service) { } 
} 

public class BasePage<T> : Page where T: Presenter 
{ 
T Presenter { get; set; } 
public BasePage() { 
    Presenter = ObjectFactory.GetInstance<T>(); //StructureMap 
} 
} 

Надеется, что это помогает!