Does a composable Application necessarily imply a Plugin based architecture - c#

I am currently working on an application and would like to add new functionality to it.
One would be to update the application's code directly.
Another would be to offer an extensibility layer where new features will be added to.
Having read multiple posts on Plugin architectures and using MEF for creating composable apps, i am a bit confused whether the 2 terms actually mean the same thing, and if not in what do they differ?
Also, i am interested to know of any good design solutions that assist in "opening up" my application to allow easier expansion in the future (new futures can be added "as an extension")

You will definitely need a plug-in based architecture to have a generic extensibility framework.
However, you do not necessarily need a Dependency Container or MEF.
It may be as simple as defining an IPlugIn interface and scanning assemblies for types implementing the interface. Then instantiating an instance of the type to get going.

Related

Dynamic object instantiation for plugin system in .NET

I'm developing a system which needs to support customization via a plugins module. I'm coding against interfaces so that plugin code only needs to implement these interfaces in order to be able to plug into the system.
// for illustration purposes; not actual code
public interface IPluggable
{
void Setup(PluginConfig c);
bool Process(IProcessable p);
}
I read from configuration which plugins need to be loaded, where the assembly name and fully-qualified type name are specified.
<plugin assembly="Foo.Bar.PluginAssembly" type="Foo.Bar.Plugins.AwesomePlugin" />
Where the type Foo.Bar.Plugins.AwesomePlugin implements IPluggable and is contained in the assembly Foo.Bar.PluginAssembly.dll. With this information I proceed to create instances of the required plugins.
IPluggable plugin = (IPluggable)Activator.CreateInstance(assemblyName, typeName).Unwrap();
So my question is threefold:
What would be a recommended pattern for a plugin system? Does the approach I'm taking make sense or are there any obvious flaws/caveats I'm missing?
Is Activator.CreateInstance() a good choice for dynamically instantiating the plugin objects?
How can I be more specific about the assembly to load and its location? Say, if I want to load plugins only from assemblies located in a .\plugins subfolder.
Answers to your questions, in order:
I like this and I use patterns like this when I need to write plug in components. Other people recommend using various frameworks - I know that MEF is very popular. But I find that using the .NET framework is easy enough for me, and learning the MEF framework is just another thing I need to learn and remember. It's probably worth a try but up to you.
I've always used Assembly.CreateInstance, but the difference is probably not going affect you (Difference between Assembly.CreateInstance and Activator.CreateInstance?)
You simply use the System.IO namespace. The DirectoryInfo class has a method that enumerates all the files matching a given pattern (presumably *.dll). For each match I'd use System.Reflection namespace to interrogate and find any types that implement your interface, and then CreateInstance.
Just on MEF, my opinion is this: if I were going to be using a large, manageable and flexible plug-in system on a number of systems or projects then I'd be very interested in it, leveraging the work that other people have done to save time and avoid common pitfalls.
If I were writing a very simple, one-off plug-in system and I know the basics of how to do so using the .NET framework, I'd skip the overhead of learning MEF and write the code. I could write a reasonable plug-in process in far less than an hour, but after downloading, referencing, attempting to configure MEF - I doubt I'd have anything to show for it.

Programming an API and programming to an interface

It is often recommended to "program to an interface, not an implementation". It is useful to promote separation of concerns, and helps with unit testing. However, I was thinking about API programming.
Let's say I wrote an API and that API used a lot of "programming to interfaces". Let's also say that the API was insanely popular and used by many external clients. If one of the interfaces in the API had to change, that would require apps using the API to be recompiled.
My question is, how is such an issue avoided (or the impact of such changes reduced), or is it unavoidable? I am not an API programer and would like to know the best practice here. It seems to me that changing an interface that has existed for a long time and is widely used is a bad idea.
Published interfaces should never change. In the case that you have to augment functionality, just add a new interface.
To quote from MSDN:
When you create an interface, you are
creating a definition that can never
change after the interface definition
has been released. This interface
invariance is an important principle
of component design, because it
protects existing systems that have
been written to use the interface.
When an interface is clearly in need
of enhancement, a new interface should
be created. This interface might be
named by appending a "2" onto the
original interface name, to show its
relationship to the existing
interface.
I think a distinction can be made here between APIs to services and APIs to libraries.
In the case of services, those APIs should not be broken. Adding interfaces to these will not impact existing consumers.
Changing a library API only requires a recompile if the consumer wants to use the newer version of the library. This is likely going to go along with a recompile anyway, and simply adding to the interface won't require existing code change (you can mark deprecated methods with attributes, if applicable).
If you actually need to make a breaking change to the API, then yes, consumers will have to change their code to make it buildable.
While this is not to be taken lightly, there are many very popular libraries whose APIs have changed significantly over time (Fluent NHibernate comes to mind), and from my perspective, at least, the pain of updating my project is minimal, especially given the improvements that come along with those updates.
I think that for libraries, there is an expectation that some adaptation may be required when adopting a new version. Likewise, there is an expectation that where the API does not change, working code should not be rendered broken by a new version.

How to better organize classes/packages in a framework so that the client of my application can easily extend them?

Let's assume I am in charge of developing a Scrabble game, being that one of the principal requirements of the client is the ability to later try out different ways and modes of the game. I already made a design that is flexible enough to support those kinds of changes. The only question left is what to expose to the client(objects' access modifiers), and how to organize it (how to expose my objects in namespaces/packages).
How should I define things such that the client can both easily use my standard implementation (a standard Scrabble game, and yet be able to make all the modifications that he wants? I guess what I need is a kind of framework, on which he can work on.
I organized my classes/interfaces in a non-strict layered system:
Data Types
Contains basic data types that might be used in the whole system. This package and its members can be accessed by anyone in the system. All its members are public.
Domain
Contains all the interfaces I've defined and that might be useful to be able to make client's new Scrabble's implementations. Also contains value types, like Piece, that are used in the game. All its members are public.
Implementations
Contains all the needed classes/code to implement my standard Scrabble game in a Implementations.StandardScrabble package. If the client decides to implement other variants of the game, he can create them in Implementations.XYZ, for example.
These classes are all package protected and the only thing that is available to the outside of the package is a Game façade. Uses both Domain and Data Types packages.
UI
Contains the UI class that I have implemented so that both the client and the users of the program can run the game (my implementation). Can access all the other layers.
There are several drawbacks to the way I am organizing things, the most obvious being that if the client wants to create its own version of the game, he will have to basically implement almost everything by himself(I share in the Domain the interfaces, but he can do almost nothing with them). I feel I should maybe pass all the Implementation's classes to the Domain and then only have a Façade that builds up my standard Scrabble in the Implementations namespace?
How would you approach this? Is there any recomended reading on how to build this kind of programs (basically, frameworks)?
Thanks
I think that you're trying to give too much freedom to a client. This must be making things that difficult for you to handle. Based on what you have described it seems that a client will be able to modify almost all parts of your game - model, logic, UI... I think it would be better to restrict modifiable areas in your application but expose some via general Plugin interface set. This would make it easier for a user as well - he will only need to learn how plugins work, not the entire application's logic. Define areas for your plugins if you want - UI plugin, game mode plugin and so on. Many production applications and games work in such way (recall Diablo II and that AMAZING variety of plugins it has!).
For the algorithms and strategies I would define interfaces and default implementations, and provide abstract superclasses which are extended by you own implementations, so that all the boilerplate code is in the abstract superclass. In addition I would allow the client to subclass your impl. Just make more than one impl, and you see what to place where.
But most important: Give your client the code. If he needs to understand where to place his code, he should be able to see what you have coded, too. No need to hide stuff.
Whatever design you come up with, I would err on the side of hiding as much of the implementation as possible. Once you expose an implementation, you cannot take it back (unless you're ready to wage a flame war with your client base). You can always provide default implementations later as you see fit.
Generally, I'd start with only providing thin interfaces. Then, before providing abstract classes, I might offer utility classes (e.g., Factories, Builders, etc.).
I'd recommend reading Effective Java by Josh Bloch for useful general practices when designing object-oriented code.
MVC/Compund Pattern
You may release earlier version of your package.
later on you can upgrade it based on user requirement.
If you are using MVC or other compound pattern wisely, I believe you also can upgrade your package easily.

Using IoC to resolve dynamically loaded types

I've written a program using Domain Driven Design in .NET 2.0 and I'm trying to implement a plugin framework for it.
I've implemented several types of plugins:
Domain Plugin
A domain aggregate composed of one or more domain classes
One or more View/Presenter pairs to display instances of the aggregate
An import/export service specific to the domain aggregate
A repository class
Service Plugins
Database Plugin (embedded or remote)
General import/export services (cvs, xml, competitor's data formats, etc)
As you can see, some plugins touch every layer of architecture. You could say that the domain plugins are miniature applications that simply depend on the main application to provide a framework in which to run. The ultimate goal is to let the user purchase and download only the plugins they need. I wrote them as static dependencies at first because I hadn't implemented a mechanism to load them dynamically. Now I'm trying to tackle the dynamic loading.
I'm trying to use an IoC container to manage the dependencies but I'm having difficulty working out how to find and load the plugins. In addition to the interfaces each plugin exposes to the main application, classes with each plugin also have their own interfaces they use to communicate with each other.
I'm using Castle Windsor as my IoC container and would like to take advantage of its autowiring capabilities both in the application and within each plugin as well.
How do I:
Find and load into Windsor implementations of a specific interface
Ensure Windsor resolves the correct one
If you think I'm going about this the wrong way feel free to say so. I still have time to change the design before my deadline.
I'm note sure I've understood you completly but consider looking at MEF (http://mef.codeplex.com/)
You could use something like the Managed Extensibility Framework to discover and enumerate your plugins at runtime. The plugins could then register the necessary types with your IoC container when they are discovered.

How should I create plugins with multiple instances in C#?

My ultimate goal is to load controls as plugins, for use as DocumentContent in AvalonDock. As a result, I will need to be able to create multiple instances of these controls, and I would prefer to do so with as limited overhead for the Plugin creators as possible.
My initial intention was to use MEF to locate and manage my plugins, but this question seems to imply that, at least at this point in time, MEF might not be intended for this.
Should I be using another solution (is the domain of DI containers, or MEF specifically, considered limited to providing instances of classes, and is there another solution that maps better to my problem), or should I use the suggested solutions (such as using reflection to clone instances, or requiring plugin creators to supply factory methods/objects - seemingly hackish) to work with/around MEF (or alternatively, is there a simple way to configure MEF to accomplish this)?
MEF's latest previews includes a type specifically for this scenario - see the blog post here: http://blogs.msdn.com/nblumhardt/archive/2009/08/28/dynamic-part-instantiation-in-mef.aspx or more info on the MEF wiki: http://mef.codeplex.com/Wiki/View.aspx?title=PartCreator&referringTitle=Home.

Categories

Resources