I don't know if this is exactly something that can help you, but if you are using a parameterless constructor on your product classes, you can use this example. Of course, implementation can be different based on your needs. The product classes can be defined in a different assembly, too.
/// <summary>
/// Product common interface.
/// </summary>
public interface IProduct
{
}
/// <summary>
/// Definition of an apple product.
/// </summary>
public class Apple : IProduct
{
public string Gauge { get; set; }
}
/// <summary>
/// Definition of a pear product.
/// </summary>
public class Pear : IProduct
{
public string Sweetness { get; set; }
}
/// <summary>
/// Factory class.
/// </summary>
public class ProductFactory
{
/// <summary>
/// List of product types found in the current assembly.
/// </summary>
private static IList<Type> ProductTypes = new List<Type>();
/// <summary>
/// Initializes the list of product types.
/// </summary>
public static void Initialize()
{
foreach (Type prodType in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
.Where(prodType => prodType.GetInterfaces().Contains(typeof(IProduct))))
{
ProductTypes.Add(prodType);
}
}
/// <summary>
/// Factory Get function.
/// </summary>
/// <typeparam name="T">Generic implementing IProduct.</typeparam>
/// <returns>Instance of the generic implementing IProduct.</returns>
public static T GetProduct<T>() where T : IProduct, new()
{
var productType = ProductTypes.Where(x => x.Name.Equals(typeof(T).Name)).FirstOrDefault();
if (productType is null) return default;
return (T)Activator.CreateInstance(productType);
}
}
/// <summary>
/// Entrypoint class.
/// </summary>
public static class Program
{
/// <summary>
/// Entrypoint method.
/// </summary>
public static void Main(string[] args)
{
// Initialize the list of product types.
ProductFactory.Initialize();
// Get an apple.
var apple = ProductFactory.GetProduct<Apple>();
// Get a pear.
var pear = ProductFactory.GetProduct<Pear>();
}
}