【问题标题】:Unified way for resolving dependencies / constructor injection解决依赖/构造函数注入的统一方法
【发布时间】:2015-10-01 09:52:49
【问题描述】:

在我看来,如何解决 XLabs 中的依赖关系有点令人困惑。

根据这里的示例项目是我如何注册依赖项(简化):

1) MainActivity.cs 中的平台依赖:

private void SetIoc()
{
    var resolverContainer = new SimpleContainer();
    resolverContainer.Register<IMediaPicker, MediaPicker>();
    Resolver.SetResolver(resolverContainer.GetResolver());
}

2) 平台独立在App.cs:

public App ()
{
    DependencyService.Register<ISettings, Settings>();
    DependencyService.Register<FooViewModel>();
}

现在,解决依赖关系相当困难。预期的方法是通过构造函数注入来解决,它以异常结束:

public FooViewModel(IMediaPicker picker) {} // Exception
public FooViewModel(ISettings settings) {} // Exception

另一种但不是最佳的方法是通过 DependencyService / Resover 解决。但在这里我需要知道我必须使用哪个:

public FooViewModel()
{
    _picker = Resolver.Resolve<IMediaPicker>();
    _settings = DependencyService.Get<ISettings>();
}

这一切对我来说似乎都不是最佳选择(例如,对于单元测试)。有没有办法统一整个解析过程,最好是通过构造函数?

【问题讨论】:

    标签: xamarin.forms xamarin.forms.labs xlabs


    【解决方案1】:

    没有理由不将您的实现放在您的构造函数中并将它们传递到堆栈中。在您的 PCL 中定义您的接口,在您的 Android 或 IOS 特定项目中实现它,并将其传递到您的 APP 构造函数的 PCL 中。它会正常工作。

    问题出现了,但是当您开始拥有超过 3 个您想要特定于平台的接口时。当您的 App 的构造函数开始变得比 MainPage 的构造函数更长时,您可能会开始寻找其他选项。

    DependencyService 是 Xamarin Forms 为您提供的一个简单的低球容器。您可以将它用于特定平台或在 PCL 内。它采用简单的形式。你注册你的接口和你想要使用的实现,然后你可以在你的 PCL 或平台特定代码的任何地方检索一个新的实现实例。使用起来很简单。 注册

    DependencyService.Register<IMyInterface,MyClass> ();  
    

    获取 MyClass 的实例只需调用

    IMyInterface me = DependencyService.Get<IMyInterface> ();
    

    我将成为一个全新的 MyClass 宝宝。

    您也可以在您的平台特定代码中调用它。

    DependencyService.Register<IMyInterface,MyAndroidVersion> (); 
    

    然后在你的 PCL 中

    IMyInterface me = DependencyService.Get<IMyInterface> ();
    

    会给你 MyAndroid 版本。

    XLabs Container 的工作方式相同,只是为您提供了更多选择。您不必同时使用两者,事实上我建议您反对它。选择三个选项之一并使用它。如果您从前两个开始,您最终可能会超过它们,因此 XLabs 可能是最佳选择。

    我个人使用 MVVMLight 的 SimpleIOC 容器。但它们基本上都是一样的,只是有一些不同的花里胡哨。

    【讨论】:

    • 感谢您的解释。在我的平台特定项目中使用DependencyService.Register&lt;T, TImpl&gt;() 方法可能会有所帮助。我会试一试。但在我看来,这仍然不是最好的方法。最好有一个依赖注入容器来解析构造函数中的所有依赖项。那么就没有必要从栈顶向下传递所有实现。实际上我希望在这行代码Resolver.SetResolver(IResolver resolver) 配置容器来执行此操作,但不幸的是它没有。
    • 在我的项目中,我通常在我的 MainPage 的构造函数中注册所有平台特定的依赖项,在我的 App 的构造函数中注册我的所有 PCL 依赖项。当然你不必这样做,但我会个人认为这是最佳实践。将注册分散在整个应用程序中会很痛苦。
    猜你喜欢
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多