首先,请允许我说我在这里读过几个关于SingleInstance的问题,但仍然无法找到有助于我的直接答案。也就是说,如果我错过任何事情,我会道歉。
这是我的问题:
我正在为iOS和Android构建一个Xamarin Forms应用程序。我在PCL中有一个AppInitializer类,我使用Autofac注册所有的接口依赖项。然后,我将构建器中的Container分配为app类的静态属性。我遇到的问题是,当我使用.SingleInstance()注册所有内容时,我实际上并没有获得单个实例。
初始化逻辑示例:
var builder = new ContainerBuilder();
builder.RegisterType<ErrorHandler>().SingleInstance().As<IErrorHandler>();
…
builder.RegisterType<MemberViewModel>().SingleInstance().As<IMemberViewModel>();
…
AppContainer.Current = builder.Build();
我让Autofac处理我的构造函数中的接口解析。例如:
public MemberViewModel(ISettingsViewModel settings, IErrorHandler errorHandler, …) : base(settings, errorHandler){…}
然后我在页面上使用所述模型如下:
示例页面使用情况:
public ProfilePage()
{
InitializeComponent();
var displayModel = Model.CurrentMember;
…
}
…
**public IMemberViewModel Model =>
AppContainer.Current.Resolve<IMemberViewModel>();**
在此示例中,我在到达此页面之前立即设置了Model.CurrentMember的属性。我设置了断点,并知道这是发生的事实。但是,当我解析模型的实例时,CurrentMember上的属性为空。
我在这里做错了还是遇到了错误?
- 编辑 - 明确表示我正在使用Autofac。
-Edit 2 - 添加更多细节。
我对IMemberViewModel类的实现有各种属性,包括一个名为current member的可观察对象。它声明如下:
public class MemberViewModel : ViewModelBase, IMemberViewModel
{
…
(see constructor above)
…
public MemberDisplay CurrentMember =>
m_CurrentMember ?? (m_CurrentMember = new MemberDisplay())
关于IMemberViewModel的实现,我有一个方法可以在CurrentMember上设置各种属性。
操作顺序如下:
最终用户点击会员的图片。这会在IMemberViewModel实现的(理论上)单例实例上触发命令。此命令执行异步任务,等待对API的异步调用以加载该成员的数据。加载数据并在CurrentMember上设置属性后,应用程序将导航到配置文件屏幕。配置文件屏幕解析IMemberViewModel(如上所述)。
预期行为: 已解析的IMemberViewModel实例的CurrentMember属性设置为刚从load数据方法设置的值。这种期望源于假设有一个IMemberViewModel实例。
实际行为 CurrentMember的属性是默认值,即string.Empty,0,null等。
这里奇怪的是,每个模型都不会发生这种情况。我有一个消息模型,我在同一个屏幕上以相同的方式解析它似乎很好。
答案 0 :(得分:0)
这个问题原因是我们开始初始化所有内容的方式。为了后人的缘故,我将简要介绍一下发生了什么以及我采取了哪些措施来阻止它。
上一个应用流程:
对流程进行更正
首先,我可以告诉我,如果在app构造函数中创建,则不需要在resume和/或start上进行init调用。如果应用被“杀死”,因为其他应用需要内存空间,则会在下次发布时创建应用的新版本(请参阅Android Activity Lifecycle和iOS App Lifecycle)。
其次,因为我是偏执狂,因为它不会受到伤害,所以在app init例程中我现在正在检查以确定容器是否存在以及接口是否已经注册。
public static void Init(ISetup setup)
{
if (Container != null && IsModelRegistered()) return;
RegisterDependencies(setup);
…
}
private static bool IsModelRegistered()
{
return Container.IsRegistered<IMemberViewModel>();
}