2009-11-10 172 views
4

我有一个ASP.NET页面实现我的视图,并在页面构造函数中创建演示者。 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实例的最佳方法?我发现这些例子在Page类中使用属​​性标记了依赖注入框架解析的属性。

但是,我更喜欢使用构造函数方法进行测试。

有没有人有输入或可能链接到上述的良好实施。我宁愿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); 
    } 
} 

服务定位有温莎城堡和StructureMap实现。不确定Ninject,但为新的IoC创建ServiceLocator适配器并不重要。

+0

我喜欢它,谢谢。 – blu

+0

使用这种方法,该视图现在知道IBlogDataService,它只应由演示者知道。有没有办法使用传递当前视图对象和配置的IBlogDataService实例的DI容器来构造演示者? – Scott

+0

使用服务定位器被认为是IoC的反模式。一定有更好的方法。 –

1

我还没有看到在webforms上进行构造函数注入的通用方法。我认为它可能通过PageFactory实现,但由于现在大多数边缘正在转向MVC而不是webforms,这可能不会发生。

然而,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 
} 
} 

希望这有助于!