派生类是否总是必须调用默认的基础构造函数?

时间:2011-12-25 05:13:29

标签: c# unity-container

我有以下内容:

    public class BaseController : Controller
    {
        protected ISequenceService _sequence;

        public BaseController()
        {
        }

        [InjectionConstructor]
        public BaseController(ISequenceService sequence)
        {
            _sequence = sequence;
        }


 public class ProductsController : BaseController
    {

        public ProductsController(
            IService<Account> accountService,
            IService<Product> productService
            ) {
            _account = accountService;
            _product = productService;   
        }

我一直在尝试我能想到的所有内容来调用BaseController 一个参数构造函数参数。但是始终会调用无参数构造函数。当我删除无参数构造函数时,我得到一个错误。

是否可以在父级中使用派生类而不使用无参数构造函数?有什么方法可以配置Unity来调用一个参数构造函数吗?

3 个答案:

答案 0 :(得分:4)

必须调用基类的 构造函数。大多数情况下,这意味着调用默认构造函数,如果你将其遗漏,它将隐式完成。您可以使用以下语法指定要调用的构造函数:

public ProductsController(IService<Account> accountService,
                          IService<Product> productService)
    : base((ISequenceService)someISequenceService) // calls the one parameter constructor
                                                   // of the base class
{
    //...
}

尝试构建派生类而不首先初始化基类是不行的。

答案 1 :(得分:0)

这实际上与Unity无关。如果您只是这样做,您会遇到相同的行为:

var prodCont = new ProductsController(accountService, productsService);

这将调用ProductsController 2参数构造函数,调用BaseController 0参数默认构造函数。

您需要做的是告诉ProductsController构造函数依次调用1参数基本构造函数而不是默认构件:

public ProductsController(IService<Account> accountService, IService<Product> productService)
    : base(sequenceService)

但是没有ISequenceService被传递给该构造函数以转发到基础构造函数,所以你可能真的想要:

public ProductsController(IService<Account> accountService,
                          IService<Product> productService,
                          ISequenceService sequenceService)
    : base(sequenceService)

假设ISequenceService也通过Unity映射。

答案 2 :(得分:-1)

你甚至可以只使用参数less constructor并使用Method Injection for parameters

public abstract class Base : IBase
>     {
> 
>         private IDep dep;
> 
>         [InjectionMethod]
>         public void Initialize(IDep dep)
>         {
>             if (dep == null) throw new ArgumentNullException("dep");
>             this.dep = dep;
> 
>             OnInitialize();
>         }
> 
>         public dep DepProperty
>         {
>             get
>             {
>                 return dep;
>             }
>         }
>         protected abstract void OnInitialize();
>     }

//now your Derived class Constructor will not be forced to have the IDep Parameter 
class Derived : Base
{
    public Derived()
    {

    }

    protected override void OnInitialize()
    {
        // you can access the baseclass dependency Instance in this override
        object depObject = this.DepProperty;
    }
}