Unity容器构造函数参数循环引用问题及解决

博客 分享
0 249
张三
张三 2022-02-26 00:55:48
悬赏:0 积分 收藏

Unity容器构造函数参数循环引用问题及解决

关键字:

Unity .NET5 .NET6 循环引用 循环依赖 Quartz StdSchedulerFactory

起因

在.NET6/.NET5环境中,使用Unity替换默认容器,用到了Quartz任务管理,发现在注册ISchedulerFactory为StdSchedulerFactory后,获取ISchedulerFactory会报错:

System.StackOverflowException:“Exception_WasThrown”

根据报错推测是产生了循环引用,导致堆栈溢出;

进一步尝试发现不用Unity用默认容器,没有这个问题;

直接看解决方法,到文章末尾。

重现

定义测试实体

public class TestModel{    public string Code { get; set; }    public string Name { get; set; }    public TestModel()    {     }    //自身引用; 注意这里    public TestModel(TestModel model)    {        this.Code = model.Code;        this.Name = model.Name;    }}

定义接口及实现

public interface ITest{    string Hello(string name);}public class TestImpl : ITest{    public TestImpl()    {    }             //用unity容器时,model定义成循环引用了,会报错    public TestImpl(TestModel model)    {    }    public string Hello(string name)    {        return $"Hello, {name}";    }}

应用

注册及获取ITest

默认容器运行正常

引用unity容器:略

再次运行,报错

解决

这是个很“奇怪”的问题,接口实现类TestImpl,因为有一个“没用到”的构造函数,其参数TestModel有一个“没用到”的构造函数,引用自身;会导致Unity容器获取该接口时报错。好绕,看图。

看“起因”Quartz中的接口实现StdSchedulerFactory,NameValueCollection有引用自身的构造函数。

解决办法:删除接口实现中的带参构造函数或自身引用的构造函数都可以;但在涉及三方dll的时候不方便。

 

更好的办法:对自身引用的参数做下注册。

public void ConfigureServices(IServiceCollection services){    //添加TestModel注册    services.AddTransient(typeof(TestModel), _ => new TestModel());    //注册ITest    services.AddScoped<ITest, TestImpl>();}

添加注册之后,运行正常。

posted @ 2022-02-25 23:55 Juntor 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员