Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Factory Pattern implementation in C#

I'm implementing a factory pattern that looks as follows.

public class FeedFactory
{
    #region Singleton Pattern
    //..
    #endregion

    private static Feed[] _factory = new Feed[(int)FeedType.Total];

    public void RegisterFeed(FeedType feedType,Feed feed)
    {
        if (_factory[(int)feedType] == null)
        {
            _factory[(int)feedType] = feed;
        }
        else
        {
            // already registered
        }
    }

    public Feed GetFeed(FeedType feedType)
    {
        return _factory[(int)feedType];
    }
}

Here, Feed is an abstract class from which the different classes inherit. How can I register the different classes? Is it possible to do it from their constructor?

like image 453
Aks Avatar asked Dec 21 '10 10:12

Aks


1 Answers

This is not a factory pattern. A factory will always have some constructor logic in it, at least one new. That's the idea of a factory: the caller doesn't have to worry about how objects are created. This is a singleton repository.

So first of all, instead of using an array, you should be having a type indexed dictionary.

private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();

After that, you don't need a register method. The dictionary should be filled automatically when you retrieve singletons.

Now I suppose your Feed class has a default constructor without arguments. In that case, you can implement a factory method directly from the abstract class Feed. We're going to use some generics here, because it allows you to control inheritance:

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

Now back to your singleton repository.

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

Note that I included a threadsafe behaviour which is a good thing to do when you work with singletons.

Now if you want to get the singleton for a given type inheriting from Feed (let's call it SpecializedFeedType), all you have to do is:

var singleton = FeedSingletonRepository.GetFeed<SpecializedFeedType>();

or

SpecializedFeedType singleton = FeedSingletonRepository.GetFeed();

which is the same line with a slightly different syntax.

Edit2: changed some syntax errors.

like image 97
Evren Kuzucuoglu Avatar answered Sep 19 '22 04:09

Evren Kuzucuoglu