C# MvvmCross上可能存在依赖项注入错误
我目前正在使用brilliant MVVMCross开发一个跨平台(Android和iOS)的应用程序,该应用程序运行得非常顺利,到目前为止没有什么大的麻烦 但是今天我碰到了一个给我带来麻烦的问题。我是关注点分离的坚定信徒,我试图做的是将一个类注册为两个不同接口的懒惰单例实现者。这是PCL中的my App.cs:C# MvvmCross上可能存在依赖项注入错误,c#,singleton,xamarin,inversion-of-control,mvvmcross,C#,Singleton,Xamarin,Inversion Of Control,Mvvmcross,我目前正在使用brilliant MVVMCross开发一个跨平台(Android和iOS)的应用程序,该应用程序运行得非常顺利,到目前为止没有什么大的麻烦 但是今天我碰到了一个给我带来麻烦的问题。我是关注点分离的坚定信徒,我试图做的是将一个类注册为两个不同接口的懒惰单例实现者。这是PCL中的my App.cs: public class App : Cirrious.MvvmCross.ViewModels.MvxApplication { public override void I
public class App : Cirrious.MvvmCross.ViewModels.MvxApplication
{
public override void Initialize()
{
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
RegisterAppStart<LoginViewModel>();
Mvx.LazyConstructAndRegisterSingleton<ISystemConfigProviderInitialiser, SystemConfigProvider>();
Mvx.LazyConstructAndRegisterSingleton<ISystemConfigProvider, SystemConfigProvider>();
}
}
我遇到的问题是,SystemConfigProvider
类被创建了多次。两次,似乎每个界面一次,这与MVVMCross wiki页面告诉我的关于服务位置和控制反转的内容相矛盾:
技术说明>这里的惰性单例实现非常技术性-它确保如果>类实现了IOne和ITwo,那么在解析IOne>和ITwo时将返回相同的实例
如果我取消了ISystemConfigProviderInitialiser
接口,并将初始化()在ISystemConfigProvider
中,只有懒洋洋的构造函数和注册器singleton在ISystemConfigProvider
接口中,就我所见,一切正常,但这意味着ISystemConfigProvider
的所有使用者现在都可以看到他们不应该看到的Initialize()方法
对此我非常感谢您的建议。这里的问题是Mvx IoC容器在接口级别处理单例方面,而不是实例化类型。因此,它没有看到
SystemConfigProvider
是相同的类型,并且应该只创建一个实例
要解决此问题,有两个选项:
1) 只需在初始化时实例化单例,然后为每个接口注册该单例:
var provider=Mvx.IocConstruct(SystemConfigProvider);
Mvx.RegisterSingleton(供应商);
Mvx.RegisterSingleton(供应商);
2) 将生成器Func传递给注册
Mvx.RegisterSingleton(()=>
{
var provider=Mvx.IocConstruct();
退货供应商;
});
Mvx.RegisterSingleton(()=>
{
var provider=Mvx.Resolve();
if(提供程序==null)
{
抛出新的InvalidOperationException(“应首先解决ISystemConfigProviderInitializer”);
}
返回(ISystemConfigProvider)提供程序;
});
我假设应该首先解析初始化器,因为有一个显式的Initialise()步骤,所以如果它为null,我会抛出一个异常
我认为选项1可能更好。它简单明了
希望这有帮助。RegisterLazySingleton也提供了一些帮助-请参阅中的
MvxLazySingletonCreator
,因此我认为您可以执行(新类型[]{typeof(SystemConfigProvider)}).AsInterfaces().RegisterAzSingleton()
-或者我们可以添加一个不太使用IEnmerable
的拉动。@slodge谢谢大家,我刚刚决定使用上面的选项1,自己实例化它,然后为两个接口注册该实例。使用此应用程序继续前进的最简单解决方案。
public class SystemConfigProvider: ISystemConfigProvider, ISystemConfigProviderInitialiser
{
public string Name {get;}
....
public string Z {get;}
public void Initialize(PocoObjToSetPropertiesAbove obj)
{
//set all properties
}
}