我正在尝试使用 winforms 应用程序来降低 IoC 的概念。假设我有一个演示者,其构造函数将其 View 和服务作为构造函数参数。所以在表单代码中我有一些相当于这个的东西:
mnPresenter = new Presenter(this, new AppService());
其中,AppService 是 IAppService 的一个实现。它已在我的
[autofac]
中注册国际奥委会容器。从这个演示者结构中获得"new"的推荐方法是什么?像我上面所说的那样,使用 IoC 框架来丢失这些"new"调用的重点不是吗?我可以做类似的事情
mPresenter = new Presenter(this, MyContainer.Resolve<IAppService>())
但这似乎违背了 IoC 的目的。我可能在这里遗漏了一些基本的东西。
如果我遗漏了一些明显的东西,请提前道歉。
最佳答案
您的问题是 View 和 Presenter 之间存在依赖循环,因为它们相互依赖。打破这种依赖循环的一般规则是回退到属性注入(inject),这也适用于您的情况。
使用 MVP,最好是让 View 通过将其注入(inject)到 Presenter 的属性中来将自己分配给创建的 Presenter:
mPresenter = container.Resolve<Presenter>();
mPresenter.View = this;
如果可以,请从应用程序中隐藏容器。由于您使用的是 MVP,因此您唯一需要直接解决的就是演示者。因此,与其让 Forms 与 Container 通信,不如让它们与静态
PresenterFactory
通信。 .这家工厂将使用盖子下的容器:mPresenter = PresenterFactory.Create<MyPresenter>();
mPresenter.View = this;
您的
PresenterFactory
可能看起来像这样: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;
}
}
您的 Composition Root 可能如下所示:
static void Main()
{
Bootstrap();
}
private static void Bootstrap()
{
var builder = new ContainerBuilder();
// TODO: register presenters
var container = builder.Build();
PresenterFactory.SetContainer(container);
}
更新
也许做这样的事情会更好:
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);
这从 View 中隐藏了演示者的实际实现,并将 View 的注册集中到演示者。
关于.net - 如何用 IoC 容器组织 MVP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11706620/