处理对象之间的循环依赖关系的最佳方法是什么?

时间:2009-05-06 19:19:31

标签: dependency-injection dependencies

在我的代码中,我有以下对象:

  • ErrorManager - 控制错误的方式 已登录应用程序
  • ConfigManager - 控制如何 获取配置信息

在我正在进行的项目中,ErrorManager需要使用ConfigManager实例提取配置信息,而ConfigManager使用ErrorManager时会发生错误。

目前,我在代码中执行以下操作:

ErrorManager _errorManager = new CustomErrorManager();
ConfigManager _configManager = new CustomConfigManager(_errorManager);
_errorManager.SetConfigurationManager(_configManager);

我有办法清理这个依赖关系的循环引用吗?

4 个答案:

答案 0 :(得分:3)

我会创建以下内容:

ErrorConfig _errorConfig = ...; 
// ErrorConfig is a new config object containing only ErrorManager Configuration
ErrorManager _errorManager = new CustomErrorManager(_errorConfig);
ConfigManager _configManager = new CustomConfigManager(_errorManager);

现在,ConfigManager可以使用准备运行的ErrorManager,而不会出现ErrorManager未准备好处理错误的引导问题。

答案 1 :(得分:2)

循环引用通常最好通过重构依赖的第三类来清理。例如,您可能会遇到以下情况:

BootstrapConfigManager _bcm = new BootstrapConfigManager();
ErrorManager _errorManager = new CustomErrorManager(_bcm);
ConfigManager _configManager = new CustomConfigManager(_bcm, _errorManager);

答案 2 :(得分:0)

重构您的代码。你可以拆分这些类来隔离一个你可以先初始化并传递给这两个类的部分。

答案 3 :(得分:0)

我会为每个名为AddRelationship的方法创建一个扩展方法,并将另一个对象作为参数传入。

传递的对象将添加关系,然后调用另一个的AddRelationship方法:

static void AddRelationship(this ConfigManager configMgr, ErrorManager errMgr)
{
    this.ErrorManager = errMgr;
    if (this != errMgr.ConfigManager)
        errMgr.AddRelationship(this);
}

static void AddRelationship(this ErrorManager errMgr, ConfigManager configMgr)
{
    this.ConfigManager = configMgr;
    if (this != configManager.errMgr)
        configMgr.AddRelationship(this);
}

这意味着您可以使用任一对象添加关系。

ConfigManager cfg = new ConfigManager();
ErrorManager err = new ErrorManager();
//Assign using either:
err.AddRelationship(cfg);
//Or
cfg.AddRelationship(err);

您还应该创建RemoveRelationship扩展。

static void RemoveRelationship(this ConfigManager configMgr, ErrorManager errMgr)
{
    if (this.errorManager == errMgr)
    {
        this.errorManager = null;
        if (errManager.configManager == this) 
            errMgr.RemoveRelationship(this);
    }
}

static void RemoveRelationship(this ErrorManager errMgr, ConfigManager cfgMgr)
{
    if (this.ConfigManager == cfgMgr)
    {
        this.configManager = null;
        if (cfgMgr.errorManager == this)
            cfgMgr.RemoveRelationship(this);
    }
}

我不知道循环引用是一个特别良好的编码实践,但这应该解决问题。