我使用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容器应该这样做。那么,我该如何解决这个错误?
答案 0 :(得分:7)
我认为你以错误的方式攻击这个。
如果您希望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
可用时设置,或者在一切可用时为您创建类实例的工厂模式。
答案 1 :(得分:3)
您似乎对IoC的工作方式感到困惑。当你想要创建一个类的实例时,没有“Magic”碰巧传递参数,如果你手动创建了一个CustomAccessAttribute的实例,Windsor将与它无关,因为它不会知道你正在创建一个实例。温莎(通常)遵循以下步骤:
这些步骤都不需要任何'Magic',但它们都要求您与容器本身进行交互,而不仅仅是新建实例并依赖DI Magic。
如果您在没有传入IUserService的情况下创建默认构造函数,您将发现如果您使用Resolve(),则无论如何都将解析IUserService,因为Windsor将始终解析具有最多参数的构造函数已注册实施。
真正的问题是,为什么属性首先需要IUserService,而它们只应用于元数据,而不是行为。我甚至不认为Windsor会在没有一堆额外设置的情况下愉快地解析属性,这暗示了它是个坏主意。