WinForm与DLL嵌套类如何共享同一Permission权限类实例
实现方案:带参数初始化的单例模式
你之前Public Shared方案失效的核心原因非常明确:你在WinForm端通过New创建的Permission实例是独立的局部对象,从未赋值给Master类的共享字段,DLL内部读取的共享字段和你WinForm端创建的实例完全是两个独立对象,自然无法同步。
你需要的本质是应用域级别的单例实现——.NET程序中EXE和其加载的DLL运行在同一个应用域内,只要把唯一的Permission实例存在共享静态字段中,所有位置访问到的都是同一个对象,完全可以实现你要的全局访问、自动同步的效果,不需要逐层传参。
具体实现步骤(VB.NET 适配你的现有代码结构)
1. 调整DLL内Master类的代码
首先收窄Permission类的构造函数权限,避免外部随意创建多实例,同时增加统一的初始化入口和全局访问点:
Public Class Master ' 存储全局唯一的Permission实例,Shared字段为应用域级别全局共享 Private Shared _permissionInstance As Permission = Nothing ' 线程锁,避免多线程环境下重复初始化生成多实例 Private Shared ReadOnly _initLock As New Object() ' 只读全局访问入口,所有位置都通过该属性获取权限实例 Public Shared ReadOnly Property Perms As Permission Get If _permissionInstance Is Nothing Then Throw New InvalidOperationException("权限模块未初始化,请先传入许可证密钥调用InitPermission完成初始化") End If Return _permissionInstance End Get End Property ' 统一初始化方法,程序启动时仅需调用一次 Public Shared Sub InitPermission(licenceKey As String) ' 双检锁保证线程安全 If _permissionInstance Is Nothing Then SyncLock _initLock If _permissionInstance Is Nothing Then _permissionInstance = New Permission(licenceKey) End If End SyncLock End If End Sub ' 嵌套权限类 Public Class Permission ' 构造函数标记为Friend,仅允许DLL内部的Master类创建实例,外部EXE无法直接New Friend Sub New(licenceKey As String) ' 保留你原有的许可证解析、权限字段初始化逻辑 End Sub ' 保留你原有的权限判断属性、方法,例如: Public Property CanAccessWorkerModule As Boolean Public Property CanAccessOtherModule As Boolean End Class ' 需要权限控制的Worker类 Public Class Worker Public Sub ExecuteTask() ' 直接读取全局权限实例判断,不需要外部传参 If Master.Perms.CanAccessWorkerModule Then ' 执行业务逻辑 Else Throw New UnauthorizedAccessException("无Worker模块访问权限") End If End Sub End Class ' 其他需要权限控制的类 Public Class OtherClass Public Sub ExecuteOtherTask() If Master.Perms.CanAccessOtherModule Then ' 执行业务逻辑 End If End Sub End Class End Class
2. 调整WinForm EXE端的初始化逻辑
废弃你之前直接New Masterclass.Permission(LicenceKey)的写法,在程序启动的最早节点(比如Program.vb的Main方法、启动窗体的构造函数中),拿到许可证密钥后调用一次初始化方法即可:
' 程序启动时仅需调用一次 Master.InitPermission(yourSavedLicenceKey)
初始化完成后,不管是WinForm端的业务代码,还是DLL内部的Worker、OtherClass,需要做权限判断时直接访问Master.Perms即可,拿到的永远是同一个实例,实例内的权限状态更新后所有位置读取到的都是最新值,完全同步。
方案说明
- 不存在EXE和DLL数据隔离的问题:.NET的
Shared(即C#中的static)字段是应用域级别的全局存储,EXE和加载的DLL在同一个应用域内访问的是同一个字段值,之前同步失败完全是因为没有把初始化好的实例赋值给共享字段。 - 从语法层面限制了多实例问题:将Permission的构造函数标记为
Friend后,外部EXE无法直接通过New创建独立的Permission实例,从根源避免了多实例不同步的问题。 - 线程安全:双检锁逻辑保证多线程场景下也不会重复初始化生成多个实例。
- 使用体验和你之前写过程代码用全局变量一致,不需要逐层传递权限实例,同时符合OOP的封装规范。
可选扩展
如果后续需要支持运行时更换许可证、刷新权限,只需要在Master类中增加对应的权限刷新方法,重新给_permissionInstance赋值为新的Permission实例即可,所有业务代码不需要做任何修改,下次访问Master.Perms时就会拿到更新后的权限对象。
内容的提问来源于stack exchange,提问作者user1500403
相关产品推荐
相关产品推荐

