【问题标题】:Does a derived class always have to call the default base constructor?派生类是否总是必须调用默认的基构造函数?
【发布时间】:2016-09-16 21:38:11
【问题描述】:

我有以下几点:

    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 one parameter 构造函数参数。但是,总是调用无参数构造函数。当我删除无参数构造函数时,出现错误。

是否可以在父类中有派生类且没有无参数构造函数?有什么方法可以让 Unity 调用单参数构造函数?

【问题讨论】:

  • C++ 有成员初始化列表来执行此操作,我相信 C# 也是如此。

标签: c# unity-container


【解决方案1】:

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

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

试图构造派生类而不首先初始化基类是行不通的。

【讨论】:

    【解决方案2】:

    这实际上与 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映射。

    【讨论】:

      【解决方案3】:

      您甚至可以只使用无参数构造函数,并为参数使用方法注入

      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;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2010-09-21
        • 1970-01-01
        • 2012-11-26
        • 2013-09-09
        • 2020-11-15
        • 1970-01-01
        • 2016-07-19
        • 2018-07-21
        • 2011-02-24
        相关资源
        最近更新 更多