如何解决替换MvvmCross
由于MvvmCross v7坚持使用自己的IoC容器,因此我想用.NET Core替换它,以便在注册IHttpClientFactory
,Polly
等第三方库时更轻松,Automapper
等通过已内置的扩展方法。
为此,我成功创建了一个实现为MvxSingleton<IMvxIoCProvider>
的类,描述如下:
public class HostingAdapter : MvxSingleton<IMvxIoCProvider>,IMvxIoCProvider
{
private IServiceProvider ServiceProvider;
private IServiceCollection ServiceCollection;
public HostingAdapter()
{
var host = Host
.ConfigureServices((context,serviceCollection) =>
{
// Configure local services
ConfigureServices(context,serviceCollection);
ServiceCollection = serviceCollection;
ServiceProvider = ServiceCollection.BuildServiceProvider();
})
.Build();
}
public void RegisterType<TFrom,TTo>() where TFrom : class where TTo : class,TFrom
{
ServiceCollection.AddTransient<TFrom,TTo>();
ServiceProvider = ServiceCollection.BuildServiceProvider();
}
public T GetSingleton<T>() where T : class
{
return ServiceProvider.GetRequiredService<T>();
}
public object GetSingleton(Type type)
{
return ServiceProvider.GetRequiredService(type);
}
..以及接口请求的所有必需方法。 然后在特定于平台的方面,我将IoC创建覆盖如下:
protected override IMvxIoCProvider CreateIocProvider()
{
var hostingAdapter = new HostingAdapter();
return hostingAdapter;
}
该代码似乎可以正常工作,但应用程序启动后,Mvx会立即注册其自己的“额外”服务,例如IMvxLoggerProvider
,IMvxSettings
等。问题来了:
-
在
-
Host
,但是Mvx在此之后仍继续注册服务。这意味着IServiceProvider与IServiceCollection不“同步”,需要新的ServiceCollection.BuildServiceProvider();
调用。我临时解决了在每次集合注册时更新提供程序的问题(例如上面的代码),但是我知道这会影响性能。有谁知道如何解决这个问题? -
有许多Mvx服务尚未注册,因此应用程序无法启动。这些是
IMvxLogProvider
,IMvxAndroidLifetimeMonitor
,IIMvxSettings
,IMvxStart
等。我只是想知道,为什么?如何让Mvx处理我的容器中所有需要启动的注册?我部分解决了其中的一些问题,例如用自定义记录器替换默认记录器的记录器,但其他InitializeLifetimeMonitor
之类的回调被称为注册太晚了。 -
除了最标准的实现之外,我还需要更改
MvxApplication
中的任何内容吗? -
我真的被迫更换标准的IoC容器吗?我该如何处理第三方库公开的
IServiceCollection
的扩展方法,例如services.AddHttpClient();
?
ServiceProvider = ServiceCollection.BuildServiceProvider();
初始化期间调用如果需要,我将使用Droid平台使用Xamarin classic。谢谢
解决方法
我受Unity.Microsoft.DependencyInjection repository的启发,已经以另一种方式解决了该问题:我取代了默认的IoC容器,而是手动初始化了一个IServiceCollection
实例,并将其添加到Mvx的IoC中提供者。
为此,我使用了以下代码:
public class App : MvxApplication
{
public override void Initialize()
{
base.Initialize();
InitializeServiceCollection();
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
RegisterAppStart<HomeViewModel>();
}
private static void InitializeServiceCollection()
{
IServiceCollection serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
MapServiceCollectionToMvx(serviceProvider,serviceCollection);
}
private static void ConfigureServices(IServiceCollection serviceCollection)
{
serviceCollection.AddHttpClient();
}
private static void MapServiceCollectionToMvx(IServiceProvider serviceProvider,IServiceCollection serviceCollection)
{
foreach (var serviceDescriptor in serviceCollection)
{
if (serviceDescriptor.ImplementationType != null)
{
Mvx.IoCProvider.RegisterType(serviceDescriptor.ServiceType,serviceDescriptor.ImplementationType);
}
else if (serviceDescriptor.ImplementationFactory != null)
{
var instance = serviceDescriptor.ImplementationFactory(serviceProvider);
Mvx.IoCProvider.RegisterSingleton(serviceDescriptor.ServiceType,instance);
}
else if (serviceDescriptor.ImplementationInstance != null)
{
Mvx.IoCProvider.RegisterSingleton(serviceDescriptor.ServiceType,serviceDescriptor.ImplementationInstance);
}
else
{
throw new InvalidOperationException("Unsupported registration type");
}
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。