如何使用IoC容器组织MVP? [英] How to organize MVP with an IoC container?

查看:60
本文介绍了如何使用IoC容器组织MVP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过Winforms应用程序来降低IoC概念.假设我有一个演示者,其构造器将其视图和服务作为构造器参数.因此,在表单代码中,我得到了一些东西:

I'm trying to get the IoC concept down with a winforms app. Say I have a presenter whose constructor takes its view and a service as constructor arguments. So in the form code I have something that amounts to this:

mnPresenter = new Presenter(this, new AppService());

其中,AppService是IAppService的实现.它已注册在我的[autofac] IoC容器中.从演示者结构中获取新"内容的推荐方法是什么?使用IoC框架失去像我在上面所做的新"调用的目的不是全部吗?

where, say AppService is an implementation of IAppService. It's registered in my [autofac] IoC container. What's the recommended way of getting the "new" out of this presenter construction? Isn't the whole point of using an IoC framework to lose these "new" calls like I'm making above?

我可以做类似

mPresenter = new Presenter(this, MyContainer.Resolve<IAppService>())

但这似乎违反了IoC的目的.我可能在这里错过了一些基本的东西.

but that seems to defeat the purpose of IoC. I'm probably missing something fundamental here.

如果我缺少明显的东西,请提前道歉.

Apologies in advance if I'm missing something obvious.

推荐答案

您的问题是,由于View和Presenter彼此依赖,因此它们之间存在一个依赖循环.打破此依赖关系周期的一般规则是回退到属性注入,这同样适用于您的情况.

Your problem is that there is a dependency cycle between the View and the Presenter, since they depend on each other. The general rule in breaking this dependency cycle is to fallback to property injection, which will work in your case as well.

使用MVP,最好的方法是将View注入到Presenter的属性中,从而将其自身分配给已创建的Presenter:

With MVP, best is to let the View assign itself to a created Presenter by injecting it into a property of the Presenter:

mPresenter = container.Resolve<Presenter>();
mPresenter.View = this;

如果可以,请从应用程序中隐藏容器.由于您正在使用MVP,因此您唯一需要直接解决的就是演示者.因此,与其让窗体与容器通信,不如让它们与静态PresenterFactory通信.该工厂将在盖子下使用该容器:

If you can, hide the container from the application. Since you are using MVP, the only things you'll ever need to directly resolve are presenters. So instead of letting the Forms communicate with the Container, let them communicate with a static PresenterFactory. This factory will use the container under the covers:

mPresenter = PresenterFactory.Create<MyPresenter>();
mPresenter.View = this;

您的PresenterFactory可能看起来像这样:

Your PresenterFactory might look like this:

public static class PresenterFactory
{
    private static IContainer container;

    public static TPresenter Create<TPresenter>()
        where TPresenter : IPresenter
    {
        return (TPresenter)
            container.Resolve(typeof(TPresenter));
    }

    public static void SetContainer(IContainer container)
    {
        PresenterFactory.container = container;
    }
}

您的合成根可能看起来像这样:

And your Composition Root might look like this:

static void Main()
{
    Bootstrap();
}

private static void Bootstrap()
{
    var builder = new ContainerBuilder();
    // TODO: register presenters

    var container = builder.Build();

    PresenterFactory.SetContainer(container);
}

更新

也许做这样的事会更好:

Perhaps even better would it be to do something like this:

interface IPresenter<TView>
{
    TView View { get; set; }
}

public static class PresenterFactory
{
    private static IContainer container;

    public static IPresenter<TView> CreateForView<TView>(TView view)
    {
        var presenter = container.Resolve<IPresenter<TView>>();
        presenter.View = view;
        return presenter;
    }
}

// View
mPresenter = PresenterFactory.CreateForView(this);

这从视图中隐藏了演示者的实际实现,并将视图的注册集中到演示者.

This hides the actual implementation of the presenter from the view and centralizes the registration of the view to the presenter.

这篇关于如何使用IoC容器组织MVP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆