Проблема с общим наследованием (открытая конструкция) - PullRequest
0 голосов
/ 13 июня 2009

Я столкнулся с этой странной проблемой при работе с базовыми базовыми классами. У меня есть три уровня иерархии базовых классов, в то время как четвертый уровень - это конкретный класс. Что-то, как показано ниже.

// Level 0 (Root Base Class)    
public abstract class BusinessDataControllerBase<BDA> : IBusinessDataController
{
    protected BDA da;
    public BusinessDataControllerBase()
    {
    // Initialize the respective Data Access Layer passed by the concrete class
    BDA da = new BDA();
    }
}


// Level 1 (Second Level Base Class)
public abstract class BusinessRootDataControllerBase<BDA> : BusinessDataControllerBase<BDA>, IBusinessRootDataController
        where BDA : IBusinessDALController, new()
{
}

// Level 2 (Third Level Base Class)
public abstract class BusinessMasterRootDataControllerBase<BRC, BRD, BDA> : BusinessRootDataControllerBase<BDA>, IDisposable
        where BRC : IBusinessRootDataController 
        where BRD : IBusinessRootData
        where BDA : IBusinessDALController, new()
{
}

// Level 3 (Concrete Class)
public class UserController : BusinessMasterRootDataControllerBase<UserController, UserData, UsersDAL>
{
        # region Singleton implementation - Private Constructor, Static initialization
        private static readonly UserController instance = new UserController();
        public static UserController Instance
        {
            get { return instance; }
        }
        # endregion

        # region Constructor
        // --------------------------------------------------------------------------------
        //Private Constuctor
        private UserController()
        {
        }
        // --------------------------------------------------------------------------------

       private void DoLogin(string userName, string password)
        {
            DataSet dstUser = da.GetUser(userName);
            // Check user name
            // Check password
        }
}

То, чего я хочу достичь, абсолютно просто. Мне нужно, чтобы объект 'da' создавался в базовом классе верхнего уровня. Конкретный тип 'UsersDAL' предоставляется конкретным классом UserController, и правильный тип должен распространяться до базового класса верхнего уровня (BusinessDataController), где он должен быть создан.

Теперь, пока я отлаживаю BusinessDataController, я вижу, что тип (UsersDAL) распространяется, создается новый объект UsersDAL () в конструкторе BusinessDataControllerBase (), но как только код выходит из конструктора в BusinessDataControllerBase переменные-члены 'da' отображаются как 'null', и, следовательно, процесс DoLogin () da.GetUser () выдает ошибку (объект не создан).

Но если вместо создания экземпляра 'da' в BusinessDataController я создам его в контроллере BusinessMasterRootData (на уровне 2, то есть в классе чуть выше конкретного класса UserController), то все работает нормально, и da.GetUser () работает как ожидается.

Я пытался изучить последствия наследования Generics (закрытая конструкция и открытая конструкция и т. Д.), Но не смог найти никаких отклонений в моем коде. Во время разработки / компиляции я не получаю никакой ошибки и не получаю все методы UsersDAL с IntelliSense, что, возможно, указывает на правильное использование типа.

Есть идеи, где я иду не так? У меня будет несколько базовых классов на третьем уровне, то есть на уровне BusinessMasterRootDataControllerBase. Таким образом, создание экземпляра «da» на третьем уровне сделает «da» доступным в конкретных классах, но будет избыточным во всех классах на этом уровне, и поэтому я хочу разместить его («da») выше. Кстати, то же самое наблюдение происходит, если я помещаю код конструктора на второй уровень (т.е. BusinessRootDataControllerBase).

Еще одна информация, которую я хочу поделиться - я использую UserController (конкретный класс) в качестве класса Singleton.

Любая помощь приветствуется.

Ответы [ 2 ]

2 голосов
/ 13 июня 2009

в

protected BDA da;
public BusinessDataControllerBase()
{
  // Initialize the respective Data Access Layer passed by the concrete class
  BDA da = new BDA();
}

Есть два элемента с именем 'da', вы назначаете новый BDA () локальной переменной, которая немедленно выходит из области видимости. Вероятно, это должно выглядеть так:

protected BDA da;
public BusinessDataControllerBase()
{
  // Initialize the respective Data Access Layer passed by the concrete class
  da = new BDA();
}
0 голосов
/ 13 июня 2009

Возможно, я просто упускаю суть, но вам следует явно вызывать конструкторы базовых классов в вашей иерархии.

Это должно работать:

// Level 0 (Root Base Class)     
public abstract class BusinessDataControllerBase<BDA> : IBusinessDataController 
{
   protected BDA da;

   public BusinessDataControllerBase()
   {
      // Initialize the respective Data Access Layer passed by the concrete class
      this.da = new BDA();
   } 
}        

// Level 1 (Second Level Base Class) public abstract class 
BusinessRootDataControllerBase<BDA> : BusinessDataControllerBase<BDA>, IBusinessRootDataController
                    where BDA : IBusinessDALController, new() 
{ 
   public BusinessRootDataControllerBase()
      : base() {}     
}

// Level 2 (Third Level Base Class) public abstract class BusinessMasterRootDataControllerBase<BRC, BRD, BDA> : BusinessRootDataControllerBase<BDA>, IDisposable
      where BRC : IBusinessRootDataController 
      where BRD : IBusinessRootData
      where BDA : IBusinessDALController, new() 
{ 
   public BusinessMasterRootDataControllerBase()
      : base() {} 
}

// Level 3 (Concrete Class) public class UserController : BusinessMasterRootDataControllerBase<UserController, UserData, UsersDAL> 
{
   # region Singleton implementation - Private Constructor, Static initialization
   private static readonly UserController instance = new UserController();

   public static UserController Instance
   {
      get { return instance; }
   }
   # endregion

   # region Constructor
   // --------------------------------------------------------------------------------
   //Private Constuctor
   private UserController()
      : base()
   {
   }
   // --------------------------------------------------------------------------------

   private void DoLogin(string userName, string password)
   {
      DataSet dstUser = da.GetUser(userName);
      // Check user name
      // Check password
   } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...