xamarin表单跨平台移动应用(iOS, Android)中的依赖注入



我目前正在尝试使用Microsoft.Extensions.DependencyInjection库将依赖注入集成到我的xamarin表单跨平台移动应用程序中。我能够在我的共享项目中注册我的服务和视图模型,但我不确定如何注册在平台特定项目中实现的服务。例如,我有一个接口(IAuthenticationService)是通过平台特定的代码实现的,所以它在我的Android和iOS项目中有实现,但我不确定如何注册我的容器,以便基于当前运行的平台使用正确的实现。下面是我在共享项目的启动类中设置DI容器的方法:

public static class Startup
{
public static IServiceProvider ServiceProvider { get; set; }
public static IServiceProvider Init()
{
// Initialize all viewmodels and services with DI container
var serviceProvider = new ServiceCollection().ConfigureServices().ConfigureViewModels().BuildServiceProvider();
ServiceProvider = serviceProvider;
return serviceProvider;
}
}
public static class DependencyInjectionContainer
{

public static IServiceCollection ConfigureServices(this IServiceCollection InServices)
{
//InServices.AddSingleton<IAuthenticationService>();
InServices.AddSingleton<ISystemLayoutModel, SystemLayoutModel>();
return InServices;
}
public static IServiceCollection ConfigureViewModels(this IServiceCollection InServices)
{
InServices.AddTransient<LoginViewModel>();
InServices.AddTransient<StartViewModel>();
InServices.AddTransient<RegistrationViewModel>();
//All other viewmodels
return InServices;
}
}

和我调用Init()在我的App.xaml.cs初始化容器与所有的服务和视图模型:

public partial class App : Application
{
public App()
{            
InitializeComponent();
Startup.Init();
MainPage = new AppShell();
}
}

每次我想注入一个依赖项到视图模型时,我在

后面的视图代码中做这样的操作
IStartViewModel _vM;
public StartPage()
{
InitializeComponent();
_vM = Startup.ServiceProvider.GetService<StartViewModel>();
BindingContext = _vM;
}

下面的视图模型看起来像这样:

class StartViewModel : ViewModelBase, IStartViewModel
{
protected ISystemLayoutModel _LayoutModel;
public StartViewModel(ISystemLayoutModel InSystemLayoutModel)
{
_LayoutModel = InSystemLayoutModel;
LoadItemsForStart();
if (_LayoutModel.SystemStartLayoutScreen.StartScreenTypes.Count < 1)
{
// Shutdown the application if it is not startup properly
Application.Current.Quit();
}
}
// More code
}

官方文档展示了如何注册DependencyService实现。

界面
public interface IPhotoPicker
{
Task<Stream> GetImageStreamAsync();
}

Android实现(构造函数)

public PhotoPicker(Context context, ILogger logger)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

在所有平台上,依赖注入容器的类型注册都是由RegisterTypes方法执行的,该方法在平台使用LoadApplication(new App())方法加载应用程序之前被调用。

Android示例

void RegisterTypes()
{
App.RegisterType<ILogger, Logger>();
App.RegisterTypeWithParameters<IPhotoPicker, Services.Droid.PhotoPicker>(typeof(Android.Content.Context), this, typeof(ILogger), "logger");
App.BuildContainer();
}

在某处调用DependencyService.Resolve<T>,将调用依赖解析方法从依赖注入容器中解析PhotoPicker类型,该容器也将解析并注入PhotoPicker构造函数中Logger类型。

async void OnSelectPhotoButtonClicked(object sender, EventArgs e)
{
...
var photoPickerService = DependencyService.Resolve<IPhotoPicker>();
var stream = await photoPickerService.GetImageStreamAsync();
if (stream != null)
{
image.Source = ImageSource.FromStream(() => stream);
}
...
}

相关内容

  • 没有找到相关文章