System.StackOverflow异常来自类之间的递归依赖

时间:2011-11-04 20:17:15

标签: c# .net dependency-injection

我在我的应用程序中使用存储库模式和服务层。为了遵循最佳实践,我正在为每个回购创建一个服务。

我的两项服务相互依赖。我需要从其他服务中至少调用一个方法。

我正在使用依赖注入来解决这些依赖关系。似乎问题源于以下几点:

  • A类依赖于B类

  • B类依赖于A类

我的DI容器解决了上述所有问题。

我调用A类,B类实例注入......

这会导致容器为B类创建一个新的A类实例....

反过来为B类注入新的A类......依此类推......

我认为这是我的一个基本设计缺陷,但我认为没有明显的方法来解决这个问题。

有什么想法吗?

示例

public UserService
{
    private readonly IUserRepository userRepo;
    private readonly ITransactionService transactionService;

    //ctor here....

    public ExampleUserMethod()
    {
         transactionService.GetTransactions();
         //do other things
    }

    public GetUsers()
    {
        //return users
    }


}

public TransactionService
{
    private readonly ITransactionRepository transactionRepo;
    private readonly IUserService userService;

    //ctor here....

    public ExampleTransactionMethod()
    {
         userService.GetUsers();
         //Do other things...
    }


    public GetTransactions()
    {
        //return transactions
    }

}

3 个答案:

答案 0 :(得分:3)

如果某些容器具有生命周期,则它们支持循环引用。这样A如果A ir请求它首先被创建并添加到缓存中。然后创建B,因为它需要作为依赖项并分配给A.因为B需要A的实例,所以请求A但不再创建,因为它在缓存中找到并且已分配此现有实例。

但我建议不要使用这个解决方案。你最好先尝试打破循环引用。循环引用从来都不是一个好主意。例如。举个例子:

public UserService
{
    private readonly IUserRepository userRepo;
    private readonly ITransactionStore transactionStore;

    //ctor here....

    public ExampleUserMethod()
    {
         transactionStore.GetTransactions();
         //do other things
    }

    public GetUsers()
    {
        //return users
    }


}

public TransactionService
{
    private readonly ITransactionStore transactionStore;
    private readonly IUserService userService;

    //ctor here....

    public ExampleTransactionMethod()
    {
         userService.GetUsers();
         //Do other things...
         transactionStore.AddTransaction(transaction);
    }
}

public class TransactionStore
{
    private readonly ITransactionRepository transactionRepo;

    public GetTransactions()
    {
        //return transactions
    }

    public AddTransaction()
    {
        //return transactions
    }
}

答案 1 :(得分:1)

根据我的理解,对DI知之甚少,与循环依赖建模的技术无关;无论如何实施,这样做总是错误的。

如果您不使用DI,您的编译器会通知您;现在,因为您将它重定位到运行时,错误会在稍后发生,运行时会通知您。

所以我的建议是删除这个循环依赖。

答案 2 :(得分:0)

解决这个问题的显而易见的方法似乎是将A类和B类都需要的所有东西都转移到C类,让A类和B类都引用(或注入)C类

但是如果没有你想要做的具体例子,很难说