FuST
FuST

Reputation: 76

Dynamically select class to use in C#

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?

Upvotes: 4

Views: 2726

Answers (4)

Tigran
Tigran

Reputation: 62248

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.

Upvotes: 7

Regfor
Regfor

Reputation: 8091

Either manually implement Factory pattern you need or use any of existing and comfortable for you Dependecy Injection/Inversion of Control containers with common interface, for example IPluging.

For example use this SO answers as base list

How do the major C# DI/IoC frameworks compare?

Upvotes: 1

vittore
vittore

Reputation: 17579

Basically you are looking for combination of Factory and Adapter patterns.

Wrap up all you objects for which "interface is not an option" into Adapters and use Factory to instantiate them, which in turn will instantiate your weird objects.

Factory design pattern - http://msdn.microsoft.com/en-us/library/ee817667.aspx

Adapter design pattern - http://www.dofactory.com/Patterns/PatternAdapter.aspx

Upvotes: 0

Mo the Conqueror
Mo the Conqueror

Reputation: 296

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

Upvotes: 2

Related Questions