构造函数不能调用自己

本文关键字:自己 调用 不能 构造函数 | 更新日期: 2023-09-27 18:17:37

我使用Castle Windsor作为DI机制,但我被困在这里了。我使用构造函数注入类型,它工作得很好。

但是,当我声明其他类的构造函数时,我需要调用默认构造函数,这是DI魔术发生的地方。

因此,我有以下代码:
private readonly IUserService UserService = null;
public CustomAccessAttribute(IUserService userService)
{
    this.UserService = userService;
}
public CustomAccessAttribute(bool someParam) : this() //here I'd like to call the above constructor
{
    ....           
}

但是我得到了错误

构造函数'CustomAccessAttribute.CustomAccessAttribute(bool)'不能调用自己

我不想把自己的userService对象放在this()调用中,因为DI容器应该这样做。如何修正这个错误呢?

构造函数不能调用自己

我觉得你的攻击方式不对。

如果你想让DI容器选择正确的重载,你必须提供你想接收的所有参数。只接受bool是没有帮助的,因为实际上还需要IUserService接口。它不会凭空出现的。您的DI需要知道它的存在,并且必须将它传递给适当的构造函数。

你需要的是:

private readonly IUserService UserService = null;
public CustomAccessAttribute(IUserService userService)
{
    this.UserService = userService;
}
public CustomAccessAttribute(IUserService userService, bool someParam) : this(userService) 
{         
}

虽然,您通常希望构造函数向外链接,从最少的参数到最多的参数。也许你想这样做:

private readonly IUserService UserService = null;
public CustomAccessAttribute(IUserService userService) : this(userService, false)
{
}
public CustomAccessAttribute(IUserService userService, bool someParam)
{  
    this.UserService = userService;
}
编辑:

如果你想传递给构造函数的bool在注入时不可用,那么构造函数注入可能根本不是要走的路。也许更合适的方法是将它设置为一个属性,一旦bool可用,就可以设置它,或者是一个工厂模式,当一切都可用时,它将为您创建类实例。

您似乎对IoC的工作方式感到困惑。当你想创建一个类的实例时,没有"魔法"碰巧传递参数,如果你手动创建一个CustomAccessAttribute的实例,Windsor将与它无关,因为它不知道你正在创建一个实例。温莎(通常)遵循以下步骤:

  1. 将IUserService的实现注册到你的容器
  2. 你调用myContainer.Resolve()(或解决与CustomAccessAttribute作为依赖的东西)
  3. 您的容器查看CustomAccessAttribute并看到构造函数接受IUserService
  4. 你的容器构建了一个IUserService的实现,并将它传递给构造函数,然后返回新的CustomAccessAttribute给你(或任何需要注入它的人)

这些步骤都不需要任何"魔法",但它们都需要你与容器本身交互,而不仅仅是新建实例和依赖DI Magic。

如果你创建了一个默认构造函数而没有传入IUserService,你会发现如果你使用Resolve(), IUserService无论如何都会被解析,因为Windsor总是用它注册实现的最多参数来解析构造函数。

真正的问题是为什么一个属性首先需要一个IUserService,当它们只应该用于元数据,而不是行为。如果没有一堆额外的设置,我甚至不认为Windsor会愉快地解析属性,这暗示了它是一个多么糟糕的主意。