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

构造依赖注入下,如何从被调用类回调至调用类存储数据?

如何在依赖注入场景下从服务类更新主类的静态列表?

千万别在PeopleService里实例化Analyzer!这会把两个类死死绑定在一起,彻底违背依赖注入“解耦”的核心设计初衷,后续维护、扩展都会变得异常麻烦,甚至可能引发生命周期管理的问题。下面给你几个更规范的实现方式,按推荐程度排序:

1. 返回包含业务结果+附加信息的复合对象(最推荐)

这种方式最直观,也符合“方法返回其执行产生的全部相关信息”的设计原则。你可以创建一个专门的DTO类,同时封装People列表和缺失项:

// 新建复合结果类,用来封装业务结果和附加信息
public class PeopleForEventResult
{
    public IList<People> People { get; set; } = new List<People>();
    public IList<string> MissingMappingItems { get; set; } = new List<string>();
}

接着修改PeopleService的方法,返回这个复合对象:

public class PeopleService : IPeopleService
{
    public PeopleForEventResult GetPeopleForEvent(string category, DateTime date)
    {
        var result = new PeopleForEventResult();
        var ppl = new List<People>();
        
        if(/* 你的原有判断条件 */)
        {
            // 原有逻辑填充ppl列表
            result.People = ppl;
        }
        else
        {
            // 将需要记录的缺失项添加到结果对象的对应列表中
            result.MissingMappingItems.Add("这里是缺失的映射项内容");
        }
        
        return result;
    }
}

最后在Analyzer中调用并处理结果:

public class Analyzer
{
    private static readonly List<string> MissingItemsInMapping = new List<string>();
    public IList<string> MissingItemsInMappingsList => MissingItemsInMapping;
    private readonly IPeopleService _peopleService;

    public Analyzer(IPeopleService peopleService)
    {
        _peopleService = peopleService;
    }

    public void YourCallingMethod(string category, DateTime date)
    {
        var result = _peopleService.GetPeopleForEvent(category, date);
        var people = result.People;
        
        // 将缺失项合并到Analyzer的静态列表中
        // 加lock是为了线程安全,如果你的场景是单线程可以去掉
        lock (MissingItemsInMapping)
        {
            MissingItemsInMapping.AddRange(result.MissingMappingItems);
        }
    }
}

2. 通过回调委托传递逻辑

如果不想新建额外的类,可以在调用服务方法时传入一个回调委托,让PeopleService直接调用这个委托来添加缺失项:

修改PeopleService的方法签名:

public class PeopleService : IPeopleService
{
    public IList<People> GetPeopleForEvent(string category, DateTime date, Action<string> addMissingItemCallback)
    {
        var ppl = new List<People>();
        
        if(/* 你的原有判断条件 */)
        {
            // 原有逻辑填充ppl列表
            return ppl;
        }
        else
        {
            // 直接调用回调委托,把缺失项传递给Analyzer处理
            addMissingItemCallback("这里是缺失的映射项内容");
            return new List<People>();
        }
    }
}

在Analyzer中调用时传入回调:

public void YourCallingMethod(string category, DateTime date)
{
    var people = _peopleService.GetPeopleForEvent(category, date, item => 
    {
        lock (MissingItemsInMapping)
        {
            MissingItemsInMapping.Add(item);
        }
    });
}

3. 使用事件通知(适合跨组件松散耦合场景)

如果PeopleService和Analyzer需要更低的耦合度,可以采用事件通知的方式:

首先在PeopleService中定义事件:

public class PeopleService : IPeopleService
{
    // 定义事件,当发现缺失映射项时触发
    public event EventHandler<string> MissingMappingItemFound;

    public IList<People> GetPeopleForEvent(string category, DateTime date)
    {
        var ppl = new List<People>();
        
        if(/* 你的原有判断条件 */)
        {
            // 原有逻辑填充ppl列表
            return ppl;
        }
        else
        {
            var missingItem = "这里是缺失的映射项内容";
            // 触发事件,通知订阅者(比如Analyzer)
            MissingMappingItemFound?.Invoke(this, missingItem);
            return new List<People>();
        }
    }
}

然后在Analyzer的构造函数中订阅事件:

public Analyzer(IPeopleService peopleService)
{
    _peopleService = peopleService;
    // 订阅PeopleService的事件
    if (_peopleService is PeopleService concreteService)
    {
        concreteService.MissingMappingItemFound += (sender, item) => 
        {
            lock (MissingItemsInMapping)
            {
                MissingItemsInMapping.Add(item);
            }
        };
    }
}

注意:这种方式需要IPeopleService暴露事件,或者向下转型到具体实现,如果你严格遵循面向接口编程,可能需要调整IPeopleService的定义,把事件加入接口中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:21:07