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

如何在C#不同解决方案间迁移依赖全局变量的共享类?

问题描述

我有两个解决方案A和B,每个解决方案包含两个项目:

  • 解决方案A:ProjectX,引用Common项目
  • 解决方案B:ProjectY,引用Common项目

Common项目包含一些独立的通用类。ProjectX和ProjectY各自拥有运行时专属的全局变量,二者均定义了如下Globals类:

public class Globals
{
    public static dynamic vaProxy;
    ...
}

在解决方案A/B运行时,会先初始化Globals.vaProxy及其他全局变量,供大量类调用,例如:

Globals.vaProxy.WriteToLog("somthing...")

或访问:

Globals.someVAriableName

我希望将ProjectX和ProjectY中的相似类迁移至Common项目以避免重复代码,但目前Common项目仅包含不依赖Globals.vaProxy或Globals.someVar的类。请问能否将依赖全局变量的类迁移至无Globals定义的Common项目?

解决方案

完全可以迁移,核心是让Common项目不直接依赖ProjectX/Y的Globals类,以下是几种实用的实现方式:

1. 依赖注入(推荐)

先在Common项目中定义抽象接口,把Globals的能力抽离出来:

// Common项目内定义
public interface IVaProxy
{
    void WriteToLog(string message);
    // 按需添加其他vaProxy的方法
}

public interface IGlobalContext
{
    IVaProxy VaProxy { get; }
    object SomeVariableName { get; }
    // 其他需要的全局变量属性
}

然后Common项目中的通用类通过构造函数注入IGlobalContext来使用全局能力:

// Common项目中的通用业务类
public class CommonBusinessService
{
    private readonly IGlobalContext _globalContext;

    public CommonBusinessService(IGlobalContext globalContext)
    {
        _globalContext = globalContext;
    }

    public void ExecuteBusinessLogic()
    {
        _globalContext.VaProxy.WriteToLog("执行通用逻辑");
        var variableValue = _globalContext.SomeVariableName;
        // 具体业务代码
    }
}

最后在ProjectX和ProjectY中,分别实现IGlobalContext接口,将各自的Globals类包装进去:

// ProjectX中的实现
public class ProjectXGlobalContext : IGlobalContext
{
    public IVaProxy VaProxy => Globals.vaProxy;
    public object SomeVariableName => Globals.someVAriableName;
}

// ProjectY中的实现类似,替换为ProjectY的Globals

运行时通过依赖注入容器注入对应的IGlobalContext实现即可。这种方式解耦彻底,扩展性强,符合SOLID原则。

2. 静态委托绑定

如果项目规模较小,不想引入DI框架,可以用静态委托的方式实现:

// Common项目内定义
public static class CommonGlobalDelegates
{
    public static Action<string> WriteToLog { get; set; }
    public static Func<object> GetSomeVariable { get; set; }
}

在ProjectX的初始化代码中(比如启动入口),绑定委托到自己的Globals:

// ProjectX启动时执行
CommonGlobalDelegates.WriteToLog = msg => Globals.vaProxy.WriteToLog(msg);
CommonGlobalDelegates.GetSomeVariable = () => Globals.someVAriableName;

Common项目中的类直接调用这些委托:

public class CommonBusinessService
{
    public void ExecuteBusinessLogic()
    {
        CommonGlobalDelegates.WriteToLog("执行通用逻辑");
        var variableValue = CommonGlobalDelegates.GetSomeVariable();
    }
}

这种方式实现简单,但耦合度比DI高,适合小型场景。

3. 反射(兜底方案,不推荐)

如果以上两种方式都无法落地,可以用反射动态获取Globals的成员,但这种方式维护成本高,耦合严重:

// Common项目中的类
public class CommonBusinessService
{
    public void ExecuteBusinessLogic()
    {
        // 根据运行环境动态获取Globals类型
        var globalsType = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(a => a.GetTypes())
            .FirstOrDefault(t => t.Name == "Globals");
        
        if (globalsType == null) throw new InvalidOperationException("未找到Globals类");

        // 获取vaProxy并调用方法
        var vaProxy = globalsType.GetProperty("vaProxy").GetValue(null);
        vaProxy.GetType().GetMethod("WriteToLog")?.Invoke(vaProxy, new object[]{"执行通用逻辑"});

        // 获取全局变量
        var variableValue = globalsType.GetProperty("someVAriableName").GetValue(null);
    }
}

这种方式不推荐,除非是遗留系统改造且无法修改现有Globals结构的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:43:07