c# - 库如何知道消费者是否实现了库接口并将其注册到 DI 容器中?
问题描述
我正在学习 Xamarin.Forms 并尝试在以下场景中使用 DI。
共享项目(或库)有一个与 DI 相关的类,如下所示。
public static class Startup
{
public static ServiceProvider CreateServiceProvider(Action<IServiceCollection> nativeConfigureServices)
{
IServiceCollection isc = new ServiceCollection();
nativeConfigureServices(isc);
ConfigureServices(isc);
return isc.BuildServiceProvider();
}
static void ConfigureServices(IServiceCollection isc)
{
// others services are omitted for the sake of simplicity
isc.AddTransient<MainPageViewModel>();
isc.AddTransient<MainPage>();
isc.AddSingleton<App>();
}
}
INativeCall
是一个可以由消费者选择实现的接口。
public interface INativeCall
{
Task FloatMessage(string msg);
}
的一个实例INativeCall
被注入 MainPage
如下。
public partial class MainPage : ContentPage
{
private readonly INativeCall nativeCall;
public MainPage(MainPageViewModel vm, INativeCall nativeCall)
{
InitializeComponent();
// others are omitted for the sake of simplicity
this.nativeCall = nativeCall;
}
private void Greeting_Clicked(object sender, System.EventArgs e)
{
nativeCall?.FloatMessage("I Love Xamarin.Forms");
}
}
然后其他特定于操作系统的项目(Android、UWP、iOS)可以INativeCall
通过nativeConfigureServices
.
为了简单起见,我选择一个Android项目如下。
public class NativeCall : INativeCall
{
public async Task FloatMessage(string msg)
{
Toast.MakeText(Application.Context, msg, ToastLength.Long).Show();
await Task.CompletedTask;
}
}
和
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
// others have been removed for simplicity
ServiceProvider sp = Startup.CreateServiceProvider(isc =>
{
isc.AddSingleton<INativeCall, NativeCall>();
});
LoadApplication(sp.GetRequiredService<App>());
}
}
问题
如果消费者(上面的Android项目)既没有实现INativeCall
也没有在DI容器中注册它,我该如何修改
private void Greeting_Clicked(object sender, System.EventArgs e)
{
nativeCall?.FloatMessage("I Love Xamarin.Forms");
}
摆脱运行时错误?
System.InvalidOperationException:“尝试激活“MainPage”时,无法解析“INativeCall”类型的服务。
换句话说,库如何知道消费者是否实现了库接口并将其注册到 DI 容器中?
解决方案
System.InvalidOperationException:“尝试激活“MainPage”时,无法解析“INativeCall”类型的服务。
这是指示MainPage
具有无法满足的构造函数依赖项的容器。
最简单的解决方案通常是更改:
public MainPage(MainPageViewModel vm, INativeCall nativeCall)
至:
public MainPage(MainPageViewModel vm, INativeCall nativeCall = null)
表示依赖项是可选的。
这将要求nativeCall
类中的所有用法都进行null
检查(因为nativeCall
可能已提供或未提供)。就像你已经在做nativeCall?.FloatMessage("I Love Xamarin.Forms");
推荐阅读
- java - 如何使用 AbstractPreAuthenticatedProcessingFilter 覆盖 AuthenticationFailure 的响应正文?
- php - Doctrine onDelete 关系 SET NULL 并设置其他字段
- excel - 如何在 Excel VBA 宏中将下拉列表的第一个值显示为默认值?
- c# - asp.net core 3.1启动添加定时器方法
- rust - 如何检查一个路径是否是另一个路径的子目录?
- azure - 如何从 Azure DevOps Pipeline 读取 Azure 文件共享文件
- multithreading - 在多线程环境中更新 geoip2 DatabaseReader
- latex - 如何在乳胶中获得作者等人等标题?
- informatica - 我怎样才能写出这样的表达式
- angular - .NET Core Identity 登录成功后返回登录页面