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

Unity容器条件依赖注入实现方案咨询(含API场景问题)

解决Unity容器下Google/Yelp服务的条件依赖注入问题

看起来你遇到的核心问题是共享的WebPortalApiClient实例被Google初始化时覆盖了AccessToken,导致Yelp调用失败——因为默认情况下Unity会注册单例实例,两个服务共用同一个对象,Google的Init调用把AccessToken设为null,直接影响了Yelp的后续使用。下面给出两种基于Unity的解决方案,帮你彻底解决这个问题:


方案一:使用Unity命名注册(Named Registrations)

给Google和Yelp分别注册独立配置好的IWebPortalApiClient实例,确保两个服务拿到的是完全隔离的对象。

步骤1:注册命名的ApiClient实例

在Unity容器配置中,分别创建Google和Yelp专属的ApiClient实例,提前完成初始化:

// 注册Google专用的ApiClient
container.RegisterType<IWebPortalApiClient, WebPortalApiClient>("GoogleApiClient", 
    new InjectionFactory(_ => 
    {
        var serverString = ConfigHelper.GetAppSetting(ConfigConstants.APIServerType);
        var server = (WebPortalServer)Enum.Parse(typeof(WebPortalServer), serverString, true);
        var apiClient = new WebPortalApiClient();
        // Google不需要AccessToken,直接初始化服务器即可
        apiClient.Init(server);
        return apiClient;
    })
);

// 注册Yelp专用的ApiClient
container.RegisterType<IWebPortalApiClient, WebPortalApiClient>("YelpApiClient", 
    new InjectionFactory(_ => 
    {
        var serverString = ConfigHelper.GetAppSetting(ConfigConstants.APIServerType);
        var server = (WebPortalServer)Enum.Parse(typeof(WebPortalServer), serverString, true);
        var apiClient = new WebPortalApiClient();
        var yelpToken = ConfigHelper.GetAppSetting(ConfigConstants.YelpApiKey);
        apiClient.Init(server, yelpToken);
        return apiClient;
    })
);

步骤2:给Google/Yelp类指定注入对应的实例

注册业务类时,明确指定要注入的命名ApiClient:

// 给Google类注入Google专用的ApiClient
container.RegisterType<IGoogle, Google>(
    new InjectionConstructor(container.Resolve<IWebPortalApiClient>("GoogleApiClient"))
);

// 给Yelp类注入Yelp专用的ApiClient
container.RegisterType<IYelp, Yelp>(
    new InjectionConstructor(container.Resolve<IWebPortalApiClient>("YelpApiClient"))
);

这样Google和Yelp各自拿到独立的ApiClient实例,再也不会互相干扰配置。


方案二:使用工厂模式(更符合单一职责)

把ApiClient的创建逻辑封装到工厂类中,让Google和Yelp通过工厂获取自己需要的实例,代码结构更清晰。

步骤1:定义工厂接口和实现

public interface IWebPortalApiClientFactory
{
    IWebPortalApiClient CreateGoogleApiClient();
    IWebPortalApiClient CreateYelpApiClient();
}

public class WebPortalApiClientFactory : IWebPortalApiClientFactory
{
    public IWebPortalApiClient CreateGoogleApiClient()
    {
        var serverString = ConfigHelper.GetAppSetting(ConfigConstants.APIServerType);
        var server = (WebPortalServer)Enum.Parse(typeof(WebPortalServer), serverString, true);
        var apiClient = new WebPortalApiClient();
        apiClient.Init(server);
        return apiClient;
    }

    public IWebPortalApiClient CreateYelpApiClient()
    {
        var serverString = ConfigHelper.GetAppSetting(ConfigConstants.APIServerType);
        var server = (WebPortalServer)Enum.Parse(typeof(WebPortalServer), serverString, true);
        var apiClient = new WebPortalApiClient();
        var yelpToken = ConfigHelper.GetAppSetting(ConfigConstants.YelpApiKey);
        apiClient.Init(server, yelpToken);
        return apiClient;
    }
}

步骤2:修改Google/Yelp的构造函数

让业务类依赖工厂,而不是直接依赖ApiClient:

public class Google : IGoogle
{
    private readonly IWebPortalApiClient _webPortalApiClient;
    public string GoogleKey { get; private set; }

    public Google(IWebPortalApiClientFactory factory)
    {
        this._webPortalApiClient = factory.CreateGoogleApiClient();
        this.GoogleKey = $"&key={ConfigHelper.GetAppSetting(ConfigConstants.Googlekey)}";
    }

    // 其他业务方法...
}

public class Yelp : IYelp
{
    private readonly IWebPortalApiClient _webPortalApiClient;

    public Yelp(IWebPortalApiClientFactory factory)
    {
        this._webPortalApiClient = factory.CreateYelpApiClient();
    }

    // 其他业务方法...
}

步骤3:注册工厂和业务类

container.RegisterType<IWebPortalApiClientFactory, WebPortalApiClientFactory>();
container.RegisterType<IGoogle, Google>();
container.RegisterType<IYelp, Yelp>();

额外优化建议:重构WebPortalApiClient的初始化方式

当前的Init方法会让实例处于可变状态,很容易出现类似的覆盖问题。建议把初始化逻辑放到构造函数中,让实例创建时就处于稳定状态:

public class WebPortalApiClient : IWebPortalApiClient
{
    public WebPortalServer WebPortalServer { get; }
    public string AccessToken { get; }

    // 用构造函数替代Init方法,确保实例不可变
    public WebPortalApiClient(WebPortalServer server, string accessToken = null)
    {
        WebPortalServer = server;
        AccessToken = accessToken;
    }

    // 移除原来的Init方法

    // 其他InvokeApi等方法保持不变...
}

这样不管用命名注册还是工厂模式,都能在创建时直接传入参数,彻底避免后续修改实例状态的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:38:14