You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin跨平台MVVM项目中单例模式失效问题及解决咨询

Xamarin单例实例重复创建问题排查与解决

初始解决方案结构

📦 Solution
 ┣ 📂 Main application
 ┃ ┣ 📂 ViewModel Project
 ┃ ┃ ┣ 📜 ...
 ┃ ┣ 📂 Android Project
 ┃ ┃ ┣ 📜 MyActivity.cs
 ┃ ┃ ┣ 📜 ...
 ┃ ┣ 📂 iOS Project
 ┃ ┃ ┣ 📜 ...
 ┗ 📂 Multiplaftorm Library
   ┣ 📂 Android-specific Library Project
   ┃ ┣ 📜 MyModuleAndroid.cs
   ┃ ┣ 📜 ...
   ┣ 📂 iOS-specific Library Project
   ┃ ┣ 📜 MyModuleiOS.cs
   ┃ ┣ 📜 ...
   ┣ 📂 Shared Library Project (.shproj)
   ┃ ┣ 📜 MyLibrary.Shared.projitems
   ┃ ┣ 📜 Service.cs
   ┃ ┣ 📜 Factory.cs
   ┃ ┣ 📜 IMyModule.cs
   ┃ ┣ 📜 ...

平台初始化相关代码

Android端初始化代码(MyActivity.cs)

[Activity(Label = "", WindowSoftInputMode = SoftInput.AdjustPan)]
public class MyActivity
{   
    protected override void OnCreate(Bundle savedInstanceState)
    {
        MyModuleAndroid.Init(this); // 需要传入Activity实例
    }

    // ... 其他代码
}

Android模块初始化逻辑(MyModuleAndroid.cs)

public class MyModuleAndroid
{
    public static void Init(Activity activity)
    {
        Factory.GetInstance().DoSomething();
    }
}

单例工厂类(Factory.cs)

public class Factory
{
    private static Factory instance;

    public static Factory GetInstance()
    {
        if (instance == null)
        {
            // 仅当实例不存在时创建新实例
            instance = new Factory(); // 原代码中NFCModuleFactory推测为笔误
        }

        return instance;
    }

    // ... 其他方法如DoSomething()
}

问题现象

模块在Android端初始化完成后,首次通过Shared项目中的Service访问Factory实例时,发现instance为空,单例会被重新创建,导致之前初始化的数据全部丢失。调试确认GetInstance()被调用两次,new Factory()执行了两次——一次是在MyModuleAndroid的Init方法中,另一次是在Service的调用中。

临时解决方案

将Factory、IMyModule等类移至单独的标准类库项目(.csproj),调整后的多平台库结构如下:

┗ 📂 Multiplaftorm Library
   ┣ 📂 Android-specific Library Project
   ┃ ┣ 📜 MyModuleAndroid.cs
   ┃ ┣ 📜 ...
   ┣ 📂 iOS-specific Library Project
   ┃ ┣ 📜 MyModuleiOS.cs
   ┃ ┣ 📜 ...
   ┣ 📂 Shared Library Project (.shproj)
   ┃ ┣ 📜 MyLibrary.Shared.projitems
   ┃ ┣ 📜 Service.cs
   ┣ 📂 Standard Project (.csproj)
   ┃ ┣ 📜 Factory.cs
   ┃ ┣ 📜 IMyModule.cs
   ┃ ┣ 📜 ...

调整后单例实例可以保持全局唯一,初始化数据不再丢失。

问题根源

Xamarin的Shared Project(.shproj)并非真正的独立程序集,它的代码会被直接嵌入到所有引用它的项目中编译:

  • Android项目引用该Shared Project时,Factory类会被编译到Android项目的程序集里
  • ViewModel/Shared项目引用该Shared Project时,Factory类又会被编译到另一个程序集里
    这两个程序集里的Factory类是完全独立的,各自拥有自己的静态instance字段,自然会出现两个不同的单例实例。

而标准的Class Library(.csproj)会被编译成一个独立的程序集,所有引用它的项目都会共享这个程序集中的类型和静态字段,因此Factory的静态instance字段是全局唯一的,单例逻辑可以正常工作。

内容的提问来源于stack exchange,提问作者Scare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 09:45:34