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

Dependency injection 什么';处理对象之间的循环依赖关系的最佳方法是什么?,dependency-injection,dependencies,Dependency Injection,Dependencies,在我的代码中,我有以下对象: ErrorManager-控制如何处理错误 已登录到应用程序中 ConfigManager—控制 获得配置信息 在我正在处理的项目中,ErrorManager需要使用ConfigManager实例获取配置信息,而ConfigManager在发生错误时使用ErrorManager 目前,我正在代码中执行以下操作: ErrorManager _errorManager = new CustomErrorManager(); ConfigManager _config

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

  • ErrorManager-控制如何处理错误 已登录到应用程序中
  • ConfigManager—控制 获得配置信息
在我正在处理的项目中,ErrorManager需要使用ConfigManager实例获取配置信息,而ConfigManager在发生错误时使用ErrorManager

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

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

我有没有办法清理依赖项的循环引用

循环引用通常最好通过重构两者都依赖的第三个类来清理。例如,您可能有如下内容:

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

重构代码。您可能可以拆分这些类来隔离一部分,您可以首先初始化该部分并将其传递给这两个类。

我将为每个被调用的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);
    }
}

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

我将创建以下内容:

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,而不会出现引导问题。

通常有大量的“管理器”类表示滥用单例模式,而不是正确的面向对象设计。我使用单例模式来承担应用程序中的特定职责(即错误管理和配置管理)。单个实例不是通过工厂模式实现的,因为我正在考虑在不久的将来向应用程序中添加一个IOC容器,以便为我处理依赖关系。现在,我只专注于解决依赖关系,这样IoC容器将是一个简单的添加;然而,我仍在学习几个不同的国际奥委会容器,所以我可能是错的。啊,你在最初的问题中没有具体说明,否则我可能没有发布。由于其他项目需求,我还没有时间调查IoC容器或依赖注入。