使用Unity Winforms MVP。注入视图时出现问题

时间:2015-04-10 17:50:33

标签: c# winforms dependency-injection unity-container mvp

我正在编写WinForms应用程序并使用某种类型的MVP模式。

到目前为止,我有这样的事情:

var mainPresenter = new MainPresenter(someusercontrol);

public MainPresenter(MainView view) 
{
      var p = new MyPresenter(view.myView)
}

public MyPresenter(MyView view) 
{
      this.view = view;

    //Some code here…
      var user = new UserService().GetUser(1);
      this.view.FirstName = user.FirstName;
      this.view.LastName = user.LastName;
}

我正在跳过很多细节,但这是主要的想法,到目前为止它运作良好。 请注意,“myView”是在设计时创建的用户控件。

现在,我正在尝试添加Unity并注入所需的视图和服务,以便我可以进行单元测试。

我的代码如下:

var mainPresenter = new DependencyFactory.Container.Resolve<IMainPresenter>();

public MainPresenter(IMainView view, IMyPresenter myPresenter) 
{
}

public MyPresenter(IMyView view, IUserService userService) 
{
      this.view = view;

    //Some code here…
      var user = userService.GetUser(1);
      this.view.FirstName = user.FirstName;
      this.view.LastName = user.LastName;
}

我能够统一创建/注入“MyPresenter”, 但问题在于,正如预期的那样,它还会创建一个新的MyView实例。因此,在MyPresenter中,不是在屏幕上获取用户控件(view.myView,在设计时创建),而是获取MyView的新实例(由Unity注入的实例)。

有人可以就如何解决或妥善完成这些建议提供一些建议吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我会查看Unity的生命周期管理文档。这是一个很好的起始链接:https://msdn.microsoft.com/en-us/library/ff660872%28v=pandp.20%29.aspx

基本上,您需要确切了解需要支持哪些方案,并确保使用正确的生命周期管理器。在这种情况下,看起来您希望Unity为MyPresenter创建MyView,然后将相同的视图传递给MainPresenter,在这种情况下,您需要PerResolveLifetimeManager。它将为每个要解决的调用启动一个实例。

编辑:添加以下示例

class Program
{
    static void Main(string[] args)
    {

        var container = new UnityContainer();

        container.RegisterType<IShared, Shared>(new PerResolveLifetimeManager());
        container.RegisterType<IChild, Child>();
        container.RegisterType<IParent, Parent>();

        var parent = container.Resolve<IParent>();

        var result = parent.Shared == parent.Child.Shared;

        Console.WriteLine("Result: {0}", result);
        Console.WriteLine("Parent Instance Count: {0}", parent.Shared.InstanceCount);
        Console.WriteLine("Child Instance Count: {0}", parent.Child.Shared.InstanceCount);
    }
}

public interface IShared {
    int InstanceCount {get;}
}

public interface IChild {
    IShared Shared {get;}
}

public interface IParent
{
    IChild Child {get;}
    IShared Shared { get; }
}

public class Child : IChild
{
    public Child(IShared shared)
    {
        Shared = shared;
    }

    public IShared Shared
    {
        get;
        private set;
    }
}

public class Shared : IShared
{
    private static int _instanceCount = 0;
    private int _myInstanceNumber = 0;

    public Shared()
    {
        _instanceCount++;
        _myInstanceNumber = _instanceCount;
    }


    public int InstanceCount
    {
        get { return _myInstanceNumber; }
    }
}

public class Parent : IParent
{
    public Parent(IChild child, IShared shared)
    {
        Child = child;
        Shared = shared;
    }

    public IChild Child { get; private set; }

    public IShared Shared { get; private set; }
}