Xamarin Forms 中的构造函数注入 .xaml.cs 文件 类

Constructor Injection in Xamarin Froms .xaml.cs file classes

我想在我的 Xamarin 项目中利用依赖项注入,但无法在 XAML 视图后面的 C# 类 中使用构造函数注入。有什么办法吗? 我看过如何在视图模型中设置依赖项注入的指南,以便稍后将它们用作存储库,但这对我不起作用。

到目前为止,我尝试了 Ninject 和 Unity。

代码: 这是我想在我的 PCL 项目中使用的服务:

public class MyService : IMyService
{
    public void Add(string myNote)
    {
        //Add Note logic
    }
}

接口:

 public interface IMyService
 {
    void Add(string myNote);
 }

App.Xaml 中的 Unity 设置:

public App ()
{
   InitializeComponent();

    var unityContainer = new UnityContainer();
     unityContainer.RegisterType<IMyService, MyService>();

    var unityServiceLocator = new UnityServiceLocator(unityContainer);              
    ServiceLocator.SetLocatorProvider(() => unityServiceLocator);

    MainPage = new MainMasterMenu(); //<-- feel that I'm missing something here as I shouldn't be creating class instances with DI, right ?
}

我希望看到的用法。这是 XAML 起始页后面的 .CS 文件:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainMasterMenu : MasterDetailPage
{
    private IMyService _myService;
    public MainMasterMenu(IMyService myService)
    {
      _myService = myService
    }

   private void SomeFormControlClickEvent(object sender, ItemChangedEventArgs e)
    {
     _myService.Add("hi");
    }
}

对于这个简单的示例,直接创建 MainMasterMenu 没有问题,但您必须将引用传递给您的服务

MainPage = new MainMasterMenu(unityContainer.Resolve<IMyService>());

但这意味着每次 MainMasterMenu 的构造函数更改时您都必须更改该行。您也可以通过注册 MainMasterMenu 来规避此问题。

unityContainer.RegisterType<MainMasterMenu>();
...
MainPage = unityContainer.Resolve<MainMasterPage>();

无论如何,任何时候你想导航到另一个页面,它需要在 unity 中注册任何依赖项,你必须确保正确解析它的依赖项,这需要(至少间接)访问 unity 容器。您可以传递一个包装器来封装对 unity

的访问
interface IPageResolver
{
    T ResolvePage<T>()
        where T : Page;
}

然后统一实施解析器

public class UnityPageResolver
{
    private IUnityContainer unityContainer;

    public UnityPageResolver(IUnityContainer unityContainer)
    {
        this.unityContainer = unityContainer;
    }

    public T ResolvePage<T>()
        where T : Page // do we need this restriction here?
    {
        return unityContainer.Resolve<T>();
    }
}

这会在 unity 中注册

unityContainer.RegisterInstance<IUnityContainer>(this);
unityContainer.RegisterType<IPageResolver, UnityPageResolver>();

但是您应该看看解决许多问题的 Prism 库 (see here)(例如,它提供了一个 INavigationService 可以让您导航到其他页面而无需关心依赖项它提供了自动解析视图模型的工具,包括依赖项)。