为了账号安全,请及时绑定邮箱和手机立即绑定

将 xamarin 表单与 IServiceProvider 一起使用

将 xamarin 表单与 IServiceProvider 一起使用

C#
侃侃尔雅 2021-09-19 16:02:14
我正在研究 xamarin 形式的&ldquo;依赖注入&rdquo;,并发现了一些使用类似ContainerBuilder. 像这样在网上找到的解决方案讨论了如何设置 DI 并将它们注入到您的视图模型中。然而,就我个人而言,由于几个原因,我没有发现这个或视图模型和绑定的整个概念非常整洁。我宁愿创建可以由业务逻辑重用的服务,这似乎使代码更清晰。我觉得实施 anIServiceProvider会导致更清晰的实施。我计划实施这样的服务提供者:IServiceProvider Provider = new ServiceCollection()                             .AddSingleton<OtherClass>()                             .AddSingleton<MyClass>()                             .BuildServiceProvider();首先,我不确定为什么没有这些的 xamarin 示例。所以,我不确定朝着这个方向前进是否有什么问题。我已经调查过了ServiceCollection。它来自的软件包Microsoft.Extensions.DependencyInjection名称中没有&ldquo;aspnetcore&rdquo;。但是,它的所有者是&ldquo;aspnet&rdquo;。我不完全确定是否ServiceCollection仅适用于 Web 应用程序,或者将其用于移动应用程序是否有意义。它是安全使用IServiceProvider与ServiceCollection只要我使用所有的单身?是否有任何问题(在性能或内存方面)我失踪了?更新注意到了一些事情:文档链接的日期与Microsoft.Extensions.DependencyInjection仍处于测试阶段的时间大致相同文档中&ldquo;使用依赖注入容器的几个优点&rdquo;列表中的所有要点也适用于DependencyInjection我所看到的。Autofac 过程似乎围绕着我试图避免使用的 ViewModel。更新 2在导航功能的帮助下,我设法将 DI 直接放入页面的后台代码中,如下所示:public static async Task<TPage> NavigateAsync<TPage>()    where TPage : Page{    var scope = Provider.CreateScope();    var scopeProvider = scope.ServiceProvider;    var page = scopeProvider.GetService<TPage>();    if (navigation != null) await navigation.PushAsync(page);    return page;}
查看完整描述

2 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

此实现使用Splat和一些帮助器/包装器类来方便地访问容器。


服务的注册方式有点冗长,但它可以涵盖我迄今为止遇到的所有用例;并且生命周期也可以很容易地改变,例如切换到服务的懒惰创建。


只需使用ServiceProvider类从代码中的任何位置的 IoC 容器中检索任何实例。


注册您的服务


public partial class App : Application

{

    public App()

    {

        InitializeComponent();

        SetupBootstrapper(Locator.CurrentMutable);

        MainPage = new MainPage();

    }


    private void SetupBootstrapper(IMutableDependencyResolver resolver)

    {

        resolver.RegisterConstant(new Service(), typeof(IService));

        resolver.RegisterLazySingleton(() => new LazyService(), typeof(ILazyService));

        resolver.RegisterLazySingleton(() => new LazyServiceWithDI(

            ServiceProvider.Get<IService>()), typeof(ILazyServiceWithDI));

        // and so on ....

    }

ServiceProvider的使用


// get a new service instance with every call

var brandNewService = ServiceProvider.Get<IService>();


// get a deferred created singleton

var sameOldService = ServiceProvider.Get<ILazyService>();


// get a service which uses DI in its contructor

var another service = ServiceProvider.Get<ILazyServiceWithDI>();

ServiceProvider的实现


public static class ServiceProvider

{

    public static T Get<T>(string contract = null)

    {

        T service = Locator.Current.GetService<T>(contract);

        if (service == null) throw new Exception($"IoC returned null for type '{typeof(T).Name}'.");

        return service;

    }


    public static IEnumerable<T> GetAll<T>(string contract = null)

    {

        bool IsEmpty(IEnumerable<T> collection)

        {

            return collection is null || !collection.Any();

        }


        IEnumerable<T> services = Locator.Current.GetServices<T>(contract).ToList();

        if (IsEmpty(services)) throw new Exception($"IoC returned null or empty collection for type '{typeof(T).Name}'.");


        return services;

    }

}

这是我的 csproj 文件。没什么特别的,我添加的唯一 nuget 包是 Spat


共享项目 csproj


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>

    <TargetFramework>netstandard2.0</TargetFramework>

    <ProduceReferenceAssembly>true</ProduceReferenceAssembly>

  </PropertyGroup>


  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

    <DebugType>portable</DebugType>

    <DebugSymbols>true</DebugSymbols>

  </PropertyGroup>


  <ItemGroup>

    <PackageReference Include="Splat" Version="9.3.11" />

    <PackageReference Include="Xamarin.Forms" Version="4.3.0.908675" />

    <PackageReference Include="Xamarin.Essentials" Version="1.3.1" />

  </ItemGroup>

</Project>


查看完整回答
反对 回复 2021-09-19
  • 2 回答
  • 0 关注
  • 241 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号