0

I have 2 classes which are derived from an abstract class

abstract class Order
{
   public virtual boolean Export()
   {
        ...
   }
}

class TradeOrder : Order
{
      public override bool Export()
      {
            //Create a new order 
      }
}

class LibraryOrder : Order
{
      public override bool Export()
      {
            //Dont create order but Update an existing order 
      }

}

TradeOrder is created for customertype "Trade" and LibraryOrder is created for customertype "Library".

The customer type will grow in near future.

How do I create instance of the derived class based on the customer type without using if...else or swicth ...case?

The instance of the class will call the export method to either create or update a sales order.

-Alan-

Alan B
  • 2,219
  • 4
  • 32
  • 62
  • How are you representing customer types in code? For example, do you have one class per customer type, with all of them deriving from a base Customer class? – Michael Liu Aug 05 '16 at 03:05
  • Does this help? http://stackoverflow.com/questions/17835839/use-an-enum-to-select-which-class-to-instantiate – sgeddes Aug 05 '16 at 03:06
  • @MichaelLiu, customerType is an enum at the moment and is defined in the calling method – Alan B Aug 05 '16 at 03:08
  • @sgeddes should add his tip as an answer; `Reflection` is going to be just about the only way you're going to pull this off. – InteXX Aug 05 '16 at 03:09
  • See the marked duplicate for advice specific to the `abstract` base class scenario. See also https://stackoverflow.com/questions/223952/create-an-instance-of-a-class-from-a-string for related advice for the more general case. If you get to a point where you have actually done some research, decided on a specific approach, and have a _specific_ question about that approach, please post a new question with a good [mcve] showing precisely what your specific issue is, along with a detailed explanation of what you've tried and what you're having difficulty with. – Peter Duniho Aug 05 '16 at 04:04

2 Answers2

1

Here is one way to achieve what you want. We can call it "convention over configuration approach" since, obviously, your derived order type names and your enum names have to match.

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var customerType = CustomerType.Library;
            var order = (Order)Activator.CreateInstance("ConsoleApplication2", "ConsoleApplication2." + customerType.ToString() + "Order").Unwrap();
        }
    }

    public enum CustomerType
    {
        Trade,
        Library
    }

    public abstract class Order
    {
        public virtual void Export() { }
    }

    public class TradeOrder : Order
    {
        public override void Export() { }
    }

    public class LibraryOrder : Order
    {
        public override void Export() { }
    }
}
Aleksandar Vucetic
  • 14,715
  • 9
  • 53
  • 56
0

I suggest have a map of object type name and Type and create instance based on the mapping. The mapping details can be initialized in the code or from external source (Ex. Config file).

    enum OrderType
    {
        TradeOrder,
        LibraryOrder
    }

    Dictionary<OrderType, Type> _orderTypeMap = new Dictionary<OrderType, Type>
    {
        { OrderType.LibraryOrder, typeof(LibraryOrder)},
        { OrderType.TradeOrder, typeof(TradeOrder)}
    };

    Order GetOrderInstance(OrderType orderType)
    {
        return Activator.CreateInstance(_orderTypeMap[orderType]) as Order;
    }
KDR
  • 478
  • 6
  • 19