Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically select class to use in C#

Tags:

c#

.net

dynamic

A little background story on this question:

I'm writing a POS system for my local bar, which I would like to be plugin-enabled. For this particular problem I'll use the following scenario:

I've got a calculator class which, as the name suggests, does all the calculations involving products on the current receipt, VAT, etc. I want this class to be extendable by a plugin (in a different assembly) to add a functionality to use these special coins we use. The calculator simply loops through all the products on the receipt (which is passed in it's constructor) to calculate the total amount. The receipt class has a list of all the product objects that are on it. The built-in product class does not have any members related to coins, these are in another product class in the plugin assembly.

The question herein is, how do I make my main program dynamically select the correct class to use for products?

I was thinking of loading all the plugins into a list or dictionary and simply loop through them to check if an override for the product class exists and then use that, but I would still need some kind of common interface, which is not an option. I know exactly how to do it in PHP, but there one can edit/replace the source with an updated one at run/install time.

Thanks in advance, Thom.

EDIT: To simplify the problem: Is it possible to have an external plugin assembly extend a built-in assembly with new methods, without having to hard-code the method's names/delegates/whatever in the existing application?

like image 689
FuST Avatar asked Dec 27 '22 05:12

FuST


2 Answers

Don't see any reason, from the question provided, to not use a common interface. Example:

public interface IProduct {

      decimal Price {get;}
}

public class Product : IProduct 
{
     decimal price;
     public decimal Price {
          get {
              return price;
          }
     }
}

public class Product1 : IProduct 
{
     decimal price;
     public decimal Price {
          get {
              return price;
          }
     }
}
....

After Calculator iterates over the collection of IProducts and call for everyone its Price property, apply region related VAT + whatever and constructs final price.

like image 78
Tigran Avatar answered Jan 08 '23 22:01

Tigran


MEF or any half decent DI container should be able to do that.. So all classes implement interface then you call RESOLVE that returns an enumerable of instances from your catalogue.

Full docs of MEF in http://msdn.microsoft.com/en-us/library/dd460648.aspx

like image 24
Mo the Conqueror Avatar answered Jan 08 '23 21:01

Mo the Conqueror