Nev*_*ane 6 architecture dependency-injection service-provider xamarin.forms
我正在研究xamarin表单上的"依赖注入",并发现了一些使用类似的概念ContainerBuilder
.在线发现的解决方案就是这样,讨论如何进行DI设置并将它们注入到视图模型中.但是,就个人而言,我没有发现这个或整个概念的视图模型和绑定非常整齐有几个原因.我宁愿创建可以被业务逻辑重用的服务,这似乎使代码更加清晰.我觉得实施一个IServiceProvider
会导致更清洁的实施.我计划实现这样的服务提供商:
IServiceProvider Provider = new ServiceCollection()
.AddSingleton<OtherClass>()
.AddSingleton<MyClass>()
.BuildServiceProvider();
Run Code Online (Sandbox Code Playgroud)
首先,我不确定为什么没有这些的xamarin例子.所以,我不确定朝着这个方向走向是否有任何问题.我已经看过ServiceCollection
课了.它来自的包Microsoft.Extensions.DependencyInjection
,名称中没有"aspnetcore".然而,它的拥有者是"aspnet".我不完全确定它ServiceCollection
是否仅适用于Web应用程序,或者将它用于移动应用程序是否有意义.
它是安全使用IServiceProvider
与ServiceCollection
只要我使用所有的单身?我有什么问题(在表现或公羊方面)我不知道了吗?
更新
在Nkosi的评论之后,我又看了一下链接并发现了一些事情:
Microsoft.Extensions.DependencyInjection
仍处于测试阶段DependencyInjection
我所见.Autofac
过程似乎围绕着我试图避免使用的ViewModels. 更新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;
}
Run Code Online (Sandbox Code Playgroud)
此实现使用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 ....
}
Run Code Online (Sandbox Code Playgroud)
服务提供商的使用
// 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>();
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的 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>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
738 次 |
最近记录: |