在我看来,如何在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>();
}
这对我来说似乎不是最优的(例如,对于单元测试)。有没有办法统一整个解析过程,在最好的情况下通过构造函数?
没有理由不把你的实现放在你的构造函数中,并把它们传递到堆栈中。在你的PCL中定义你的接口,在你的Android或IOS特定的项目中实现它,并将它传递到你的APP构造函数的PCL中。没问题的。
问题出现了,但当你开始有超过3个接口,你想是特定于平台。当你的App的构造函数开始比MainPage的构造函数长时,你可能会开始寻找其他的选项。
DependencyService是Xamarin Forms提供给你的一个简单的low ball容器。您可以将其用于特定平台或在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容器。但它们基本上都是一样的,只是有一些不同的特点。