[C#, .NET] EntityFactory Design

Started by
3 comments, last by Maxamor 17 years, 9 months ago
First and foremost: my EntityFactory class is not a Factory as defined by the Factory Pattern. The EntityFactory I wrote is just an easier way for me to get instances of my Entity classes without hard-coding a call to the class constructors every time I want one. This post is about the opinions of other coders who have experience with C#/.NET Framework and the way in which I create the instances of my Entity classes. Here's how the class works:
public class EntityFactory
{
   private Dictionary<String, Type> entityLibrary;

   ...some more code here...

   private void GenerateEntityLibrary()
   {
            entityLibrary.Add("Metool", typeof(MetoolEntity));
            // Add more entity subclass types as they are created...
   }

   public Entity CreateEntity(String name)
   {
            // Lookup the entity in the Dictionary.
            if (entityLibrary.ContainsKey(name))
            {
                Type entityType = entityLibrary[name];
                return entityType.InvokeMember(null,
                    BindingFlags.DeclaredOnly |
                    BindingFlags.Public | BindingFlags.NonPublic |
                    BindingFlags.Instance | BindingFlags.CreateInstance,
                    null,
                    null,
                    null
                ) as Entity; // Return a Clone of the Entity.
            }
            else
                return null;
   }

   ...probably some more code here too...
}


So, GenerateEntityLibrary() will eventually add all of the Entity subclasses' Types to the Dictionary and associate them with the String I want to use as a reference to them. When I want an instance of my Entity, CreateEntity(String name) looks up the name in the Dictionary and if it's found, uses reflection to create an instance of the class. There were reasons I didn't want to give my abstract Entity baseclass a .Clone() method and that's why I came up with this code. In your opinions, is this a good way of going about it? Did I over complicate it? P.S. Yes, it's a Metool from Megaman... [Edited by - Maxamor on June 27, 2006 4:38:07 PM]
Advertisement
Quote:

In your opinions, is this a good way of going about it?


No, for about a half dozen reasons. The most important is that using this eliminates type safety, which is a very useful tool for proper software design.
Quote:Original post by Telastyn
No, for about a half dozen reasons. The most important is that using this eliminates type safety, which is a very useful tool for proper software design.


Any recommendations? I thought that the design was good because I can just ask for an Entity (or any subclass of one) and it returns one as long as it was added when I generate the entity library.

I feel for not seeing how this is not type-safe. I understand that using the InvokeMethod returns an Object, which has to be casted. But since the only things that that will be stored in my Dictionary are subclasses of Entity, there should be no problem. Right?
Alright, perhaps I was a bit harsh, but you've not described the use cases for this thing. This in particular:
Quote:
The EntityFactory I wrote is just an easier way for me to get instances of my Entity classes without hard-coding a call to the class constructors every time I want one.


Strikes me as making a factory for some arbitrary reason. The fact of the matter is that hard-coding the constructor call is usually what you want to do.

Let's look at this another way... The very first statement:
Quote:
First and foremost: my EntityFactory class is not a Factory as defined by the Factory Pattern


So, what is different? Why is a common Factory or one of its variants insufficient? It certainly looks like a Pluggable Factory to me... If you do just need a plugable factory, why use reflection; it doesn't really give you anything over standard delegate registry?

What does this abstraction gain you?


Quote:
But since the only things that that will be stored in my Dictionary are subclasses of Entity, there should be no problem. Right?

No, that code will take any type; it'll just return null (after doing all of the work to parse the creation string and reflecting up an instance) if the target isn't convertable to Entity.
So, I have modified my EntityFactory so that it is more type-safe. I changed the following:

private Dictionary<String, Entity> entityLibrary;public Entity CreateEntity(String name)        {            // Lookup the entity in the Dictionary.            if (entityLibrary.ContainsKey(name))            {                Type entityType = entityLibrary[name].GetType();                return entityType.InvokeMember(null,                    BindingFlags.DeclaredOnly |                    BindingFlags.Public |                     BindingFlags.NonPublic |                    BindingFlags.Instance |                     BindingFlags.CreateInstance,                    null,                    null,                    null                ) as Entity; // Return a Clone of the Entity.            }            else                return null;        }


I'm thinking about changing the return null to throw an exception instead, that way I'll never get a null return from this function.

Do you think this is an improvement? I am still a bit confused using delegates/callbacks and that is why I have done it this way.

This topic is closed to new replies.

Advertisement