Creating a Plug-in Architecture in .NET @OndrejBalas
Jan 28, 2015
Creating a Plug-in Architecturein .NET
@OndrejBalas
Ondrej Balas• Husband & Father• Small Guy, Big Data• Owner of UseTech Design• I build software that drives business
Blog: http://www.ondrejbalas.com Twitter: @OndrejBalas
Plug-in Architecture
• An external piece of functionality that may be added to an existing system by abiding by a contract pre-defined by that system.
Plug-in (my definition)
Interface Segregation
Examples of Plug-ins
Benefits
Benefits• Split work across natural boundaries• Incrementally create and deploy features• Deploy only new and updated modules• Don’t need source code for existing
system
New & Old
Licensing Flexibility
• Changes to contracts are difficult to manage• Increased development time for
small projects
Drawbacks
But How?
// Get input – “HELLO”string input = Console.ReadLine().ToUpper(); // "Encrypt" itstring output = "";foreach (char c in input){ byte b = (byte) c; output += (char)(b < 78 ? b + 13 : b - 13);}
// Write output – “URYYB”Console.WriteLine(output);
Dependency Inversion
Tightly Coupled Code
static void Main(string[] args) { // Get input string input = Console.ReadLine().ToUpper();
// "Encrypt" it Rot13 encryptionAlgorithm = new Rot13(); string output = encryptionAlgorithm.Encrypt(input);
// Write output Console.WriteLine(output);}public class Rot13 { public string Encrypt(string input) { string output = ""; foreach (char c in input) { output += (char)(c < 78 ? c + 13 : c - 13); } return output; }}
static void Main(string[] args) { // Get input string input = Console.ReadLine().ToUpper();
// "Encrypt" it IEncryptionAlgorithm encryptionAlgorithm = new Rot13(); string output = encryptionAlgorithm.Encrypt(input);
// Write output Console.WriteLine(output);}
public class Rot13 : IEncryptionAlgorithm { public string Encrypt(string input) { string output = ""; foreach (char c in input) { output += (char)(c < 78 ? c + 13 : c - 13); } return output; }}
public interface IEncryptionAlgorithm{
string Encrypt(string input);}
DecoupledCode
Code Sample
Dependency Injection
Dependency Injection
Dependency Injection
Dependency Injection
Dependency InjectionCode Sample
Plugins!
Code Sample
• Single - Automatically choose one.• One of Many - Like Single, but give the user
the choice. Think smart phone apps• Many Simultaneously – Using the composite
pattern, many plug-ins are treated as one. Like browser plug-ins; they have the potential of overlapping
Plug-in Strategies
• Most IoC containers– Ninject (using ninject.extensions.conventions)– Castle.Windsor– Unity– StructureMap– MEF – Managed Extensibility Framework– MAF – Managed AddIn Framework– Many other IoC containers
Frameworks
MVC ExampleSite Demo
Add Sales Tax to Calculation
Toppings!More Toppings!
RequirementsPlugin Demo
Big Al’s Plug-inCode Sample
Papa’s Plug-inCode Sample
A New ClientCode Sample
• Why not use config files? Config files are for changing the data/data source. Plug-in architecture is for dropping in functionality
• Deciding where to put plug-in points
Discussion
• Recovering from plug-in crashes• Dynamic loading and unloading at run time• Updating an application while it’s running
Endless Possibilities
@OndrejBalas
Thanks!Questions? E-mail or Tweet me
https://github.com/ondrejbalas/plugin-architecture
@OndrejBalas
Thanks!Questions? E-mail or Tweet me
https://github.com/ondrejbalas/plugin-architecture
@OndrejBalas
Thanks!Questions? E-mail or Tweet me
https://github.com/ondrejbalas/plugin-architecture
@OndrejBalas
Thanks!Questions? E-mail or Tweet me
https://github.com/ondrejbalas/plugin-architecture
@OndrejBalas
Thanks!Questions? E-mail or Tweet me
https://github.com/ondrejbalas/plugin-architecture
Any further and you will see my unused slides
• Single - Automatically choose one.• One of Many - Like Single, but give the user
the choice. Think smart phone apps• Many Simultaneously – Using the composite
pattern, many plug-ins are treated as one. Plug-ins can interfere with each other using this strategy. Like browser plug-ins; they have the potential of overlapping
Plug-in Strategies
• Dependency Injection• Composite Pattern
Plug-in Patterns
• Single (Plug-in replaces functionality)• Multiple (Different implementations of the
same thing – examples doing stuff with files, compression, encryption)• Multiple (Each plug-in has different
functionality like iphone apps)• Single > Multiple would use the Composite
Pattern. Multiple should use Composite
Plug-in Architectures in the wild
Code to Interface = Code to Contract
• It’s just broken out into optional assemblies
• Plugins work due to the concept of abstractions or programming to interface and the idea of composable parts
• The basic idea is that your application loads pieces which by default can be nullable but be replaced by the client
The Client - Big Al’s Pizza Pies
• Like most of our clients, wants “mostly custom” without “custom” cost
• Buys our software which is customizable by way of plugin
• Nephew can code in C# and make changes
More toppings
Sales tax for customers on the other side of the river
Delivery Charges Extra
• Uhoh.. We didn’t give them enough plugin points to be able to do what they want to do.
• This shows one of the pain points – if we don’t think of it, they’ll have to wait for the next version that will include it.
• A new client can get hook points in their own branch that can be merged into the master later
• It isn’t perfect, but it’s a good solution that buys us a lot of flexibility. Piecemeal functionality, deployed to customer’s site, and customer can customize the code as needed – to a point
Where to make plugin points
A La Carte
More Benefits
• Replace or accentuate existing code with dropped in code
• Doesn’t require recompiling the original project OR having the source code
• Plugins are usually not required
Config Files?
Text
Why
Applications become more like Frameworks