Общий абстрактный синглтон с пользовательским конструктором в C # - PullRequest
2 голосов
/ 26 апреля 2010

Я хочу написать общий синглтон с внешним конструктором. Другими словами, конструктор может быть изменен. У меня в голове 2 дизайна, но я не знаю, практичны они или нет.

  • Первый - заставить конструктор производного класса быть закрытым, но я не знаю, есть ли способ?

  • Второй - использовать делегат и вызывать его внутри конструктора?

Не обязательно быть конструктором. Причиной, по которой я выбрал собственный конструктор, является выполнение некоторых пользовательских инициализаций.

Любые предложения будут оценены:)

Ответы [ 5 ]

2 голосов
/ 31 октября 2011

Это моя точка зрения, используя .NET 4

public class Singleton<T> where T : class, new()
    {
        Singleton (){}

        private static readonly Lazy<T> instance = new Lazy<T>(()=> new T());

        public static T Instance { get { return instance.Value; } } 
    }
2 голосов
/ 26 апреля 2010

Вот один из способов сделать это, если я смогу вас правильно понять.

public abstract class MySingletonBase<T>
    where T : class
{
    protected MySingletonBase()
    {
    }

    // All other functions that will be inherited.
}

public class MySingleton<T> : MySingletonBase<T>
    where T : class
{
    private static MySingleton<T> instance;
    protected MySingleton()
    {
    }

    public static MySingleton<T> GetInstance()
    {
        if (instance == null)
        {
            instance = new MySingleton<T>();
        }
        return instance;
    }
}
2 голосов
/ 26 апреля 2010

Звучит не очень хорошо. Интересно, будет ли настройка этого через IoC проще и проще в поддержке? Большинство IoC-контейнеров поддерживают повторное использование объектов в едином стиле и настраиваемую инициализацию крайне . Без побочных эффектов, делающих ваш объект безобразным.

Синглтон хорош, но сильно используется. Конечно, я виновен в этом так же, как и следующий гик ...

0 голосов
/ 29 апреля 2010

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

0 голосов
/ 26 апреля 2010

Хорошо, вот мое решение. Я использовал отражение, чтобы проверить общедоступных конструкторов. Пожалуйста, прокомментируйте, если я что-то упустил.

      public abstract class Singleton<T> where T: class
      {

        private static volatile T _instance;

        private static object _lock = new object();

        protected Singleton()
        {
          ConstructorInfo[] constructorPublic = typeof(T).GetConstructors(BindingFlags.Public | BindingFlags.Instance);
          if (constructorPublic.Length > 0)
          {
            throw new Exception(String.Format("{0} has one or more public constructors so the property cannot be enforced.",
                                              typeof(T).FullName));
          }
        }

        public static T Instance
        {
          get
          {
            if (_instance == null)
            {
              lock (_lock)
              {
                if (_instance == null)
                {
                  ConstructorInfo constructorNonPublic = null;

                  try
                  {
                    constructorNonPublic = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null,
                                                            new Type[0], null);
                  }
                  catch (Exception e)
                  {
                    throw e;
                  }

                  if (constructorNonPublic == null || constructorNonPublic.IsAssembly)
                  {
                    throw new Exception(String.Format("A private or protected constructor is missing for {0}",
                                                      typeof (T).Name));
                  }

                  _instance = constructorNonPublic.Invoke(null) as T;
                }
              }
            }

            return _instance;
          }
        }
      }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...