简体   繁体   中英

Simple Factory with reflection C#

Simple factory using reflection involves storing (registering) various type names with their corresponding class type in a hash table, then using this hash table for generating objects in the factory.

interface Product
{
    void foo();
}
class ProductFactory
{
    HashTable m_RegisteredProducts = new HashTable();
    public void registerProduct(string productID, Type p)    {
        m_RegisteredProducts.add(productID, p);
    }

    public Product createProduct(string productID){
        return (Product) new m_RegisteredProducts[productID];
    }
}

I'm not clear on when does the process of registering a new type happen since all types to be used are to be loaded into the hash table at runtime. Where is the call to registerProduct() to be made?

  1. Calling registerProduct() for all different classes at a single place inside ProductFactory class doesn't make sense since it would defeat the purpose of using reflection over naive switch/case method.
  2. If registerProduct() is called inside the class definition of all classes implementing the interface, then an instance of the class is created after/using the Factory hence will always give an error.

Your code doesn't do reflection as it's expecting an instance implementing the Product interface, not a type. You would need addProduct to take a Type instance, check if it implements the Product interface, then dynamically create instances of it in createProduct (using something like type.GetConstructor(<constructor signature>).Invoke(<arguments>); )

Here's an article I wrote a long time ago on something similar: http://blixt.org/2009/06/05/getting-types-implementing-class-or-interface

  1. Calling registerProduct() for all different classes at a single place inside ProductFactory class doesn't make sense since it would defeat the purpose of using reflection over naive switch/case method.

Reflection is useful when extended product classes are added into a location (say a plug-ins directory). You have a list of strings to identify the supported plug-ins that can either be defined in a text file (application properties, which provides an added layer of security) or by (via reflection) scanning said plug-ins directory (less secure if someone can drop a hacked product in there). Disclaimer: I've never done this in C#, but it works well in Java. Apart from new product code and eventually modifying the properties file, there is no modification to the application code.

  1. If registerProduct() is called inside the class definition of all classes implementing the interface, then an instance [of] the class is created after/using the Factory hence will always give an error.

I'm not sure that's always the strategy of the code in your question (where is it from?). You might want to read more about the different strategies of reflection combined with simple factory at http://www.codeproject.com/Articles/37547/Exploring-Factory-Pattern

It depends. There are different scenarios that call for different strategies. One strategy that I saw quite often if all product types are defined in the same assembly (or a list of assemblies) you could call something like this:

var productTypes= from t in Assembly.GetExecutingAssembly().GetTypes()
                  where t.GetInterfaces().Contains(typeof(IProduct));

and then call registerProduct() for every element in productTypes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM