如何将多个演示者注入主演示者

本文关键字:注入 | 更新日期: 2023-09-27 18:31:13

根据这个答案,我可以将依赖项注入构造函数。 但是,如果假设我有 10 个"副演示者"怎么办?我应该通过构造函数注入所有这些吗? 在这种情况下,建议使用什么设计模式(工厂方法、立面等)? 如果您能提供示例代码来使用 NUnit 和 NSubstitute 对其进行测试,我将不胜感激? 提前感谢!

public void PresenterMain(IViewMain view
, IServiceMain service
, IAddNewJobPresenter addNewJobPresenter
, IClientManagementPresenter clientManagementPresenter
, IJobBatchesPresenter jobBatchesPresenter
, IReportsPresenter reportPresenter...etc)

如何将多个演示者注入主演示者

鉴于使用者需要使用 10 个演示器实例,有几个选项。下面是设置方案的一些基本框架:

public interface IPresenter
{
    void Present();
}
public interface IConsumer
{
    void DoSomething();
}
public class SomeConsumer : IConsumer
{
    private readonly IPresenter presenter;
    public SomeConsumer(IPresenter presenter)
    {
        if (presenter == null)
            throw new ArgumentNullException("presenter");
        this.presenter = presenter;
    }
    public void DoSomething()
    {
        this.presenter.Present();
    }
}

您可以使用复合模式,然后可以在列表中对演示者进行排序。

public class Presenter1 : IPresenter
{
    public void Present()
    {
        // Do something here
    }
}
public class Presenter2 : IPresenter
{
    public void Present()
    {
        // Do something here
    }
}
public class Presenter3 : IPresenter
{
    public void Present()
    {
        // Do something here
    }
}
public class CompositePresenter : IPresenter
{
    private readonly IPresenter[] presenters;
    public CompositePresenter(IPresenter[] presenters)
    {
        if (presenters == null)
            throw new ArgumentNullException("presenters");
        this.presenters = presenters;
    }
    public void Present()
    {
        // Do nothing except delegate the call to the nested
        // instances. You may need to do some extra work to deal
        // with multiple return values, like add up the values
        // or decide which value works best for the scenario.
        foreach (var presenter in this.presenters)
        {
            presenter.Present();
        }
    }
}

然后像这样连接起来:

var presenter1 = new Presenter1();
var presenter2 = new Presenter2();
var presenter3 = new Presenter3();
var compositePresenter = new CompositePresenter(new IPresenter[] {
    presenter1,
    presenter2,
    presenter3
});
var consumer = new SomeConsumer(compositePresenter);

或者您可以使用装饰器模式:

public class Presenter1 : IPresenter
{
    public Presenter1(IPresenter innerPresenter)
    {
        if (innerPresenter == null)
            throw new ArgumentNullException("innerPresenter");
        this.innerPresenter = innerPresenter;
    }
    public void Present()
    {
        // Do something here
        // You could make this call conditional
        this.innerPresenter.Present();
        // Or do something here
    }
}
public class Presenter2 : IPresenter
{
    public Presenter2(IPresenter innerPresenter)
    {
        if (innerPresenter == null)
            throw new ArgumentNullException("innerPresenter");
        this.innerPresenter = innerPresenter;
    }
    public void Present()
    {
        // Do something here
        // You could make this call conditional
        this.innerPresenter.Present();
        // Or do something here
    }
}
public class Presenter3 : IPresenter
{
    public Presenter3(IPresenter innerPresenter)
    {
        if (innerPresenter == null)
            throw new ArgumentNullException("innerPresenter");
        this.innerPresenter = innerPresenter;
    }
    public void Present()
    {
        // Do something here
        // You could make this call conditional
        this.innerPresenter.Present();
        // Or do something here
    }
}
public class NullPresenter : IPresenter
{
    public void Present()
    {
        // Do nothing here - this class is a placeholder
        // in case you want to expand the design later
    }
}

然后像这样连接起来:

var nullPresenter = new NullPresenter();
var presenter3 = new Presenter3(nullPresenter);
var presenter2 = new Presenter2(presenter3);
var presenter1 = new Presenter1(presenter2);
var consumer = new SomeConsumer(presenter1);