Это не заводской шаблон.У фабрики всегда будет какая-то логика конструктора, по крайней мере, одна new
.Это идея фабрики: вызывающей стороне не нужно беспокоиться о том, как создаются объекты.Это одноэлементное хранилище.
Итак, во-первых, вместо использования массива у вас должен быть индексированный словарь типов.
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
После этого вам не нужензарегистрировать метод.Словарь должен заполняться автоматически, когда вы извлекаете синглетонов.
Теперь я предполагаю, что ваш класс Feed имеет конструктор по умолчанию без аргументов.В этом случае вы можете реализовать фабричный метод непосредственно из абстрактного класса Feed.Здесь мы собираемся использовать некоторые обобщения, поскольку они позволяют вам управлять наследованием:
public abstract class Feed
{
public static T GetInstance<T>() where T:Feed, new()
{
T instance = new T();
// TODO: Implement here other initializing behaviour
return instance;
}
}
Теперь вернемся к вашему одноэлементному репозиторию.
public class FeedSingletonRepository
{
private static readonly object _padlock = new object();
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
public static T GetFeed<T>() where T:Feed
{
lock(_padlock)
{
if (!_singletons.ContainsKey(typeof(T))
{
_singletons[typeof(T)] = Feed.GetInstance<T>();
}
return (T)_singletons[typeof(T)];
}
}
}
Обратите внимание, что я включил поточно-безопасное поведениечто хорошо делать при работе с синглетами.
Теперь, если вы хотите получить синглтон для заданного типа, унаследованного от Feed
(назовем его SpecializedFeedType
), все, что вам нужно сделатьэто:
var singleton = FeedSingletonRepository.GetFeed<SpecializedFeedType>();
или
SpecializedFeedType singleton = FeedSingletonRepository.GetFeed();
, что является той же строкой с немного другим синтаксисом.
Edit2: изменены некоторые синтаксические ошибки.