How to create a loosely coupled architecture with hot-swap capability? - c#

I'm interested in creating a desktop application composed of modules such that the source code to those modules is embedded in the application itself, allowing the user to edit the application as they are running it and have the updated modules put into use without restarting the application. Can anyone suggest a good architecture for this?
I'm looking to use Microsoft.Net and C# for this. DLR is not an option.
Thanks!

It's not easy to suggest a good architecture for this in a short posting.
At first, i'd define a contract (an Interface) every module the user writes/modifies must implement. It should contain at least an Execute method.
Then I'd create a Wrapper-Class for these modules which:
loads the source code from a file
The wrapper compiles the file and also makes sure it implements the contract
Contains an indicator of whether the file could be compiled sucessfully
It should also implement the contract, for easy calling and handling
Then I'd have some kind of shell which contains a collection of all the module-wrappers. Any wrapper that sucessfully compiled would then let the Shell call the Execute method of the module interface.
When it comes to compiling and executing code on the fly, this link should provide all the information you need:
http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm

Well, a dynamic language certainly would have been the best fit...
You can use the types in the System.Reflection.Emit namespace to dynamically create assemblies.
However, it's going to be really painful because you'd need to load those dynamic assemblies into custom AppDomains because otherwise you'll not be able to unload them again.
This again means that you must address marshalling and assembly resolution issues related to cross-AppDomain communication.

What you are probably looking for is the concept of Dependency Injection.
Dependency Injection means that instead of having module X use module Y directly, module X only relies on an interface, and the application tells module X which implementation should use for it, e.g. using module Y.
There are several ways of implementing Dependency Injection. One is to have references to the interfaces in each of your modules, and explicitly let the application configure each of its modules with the right implementation of the interface.
The second wahy of implementing it (and probably the most useful in your case) is by using a central registry. Define all the interfaces that you want to have in your application. These are the interface for which you want to dynamically change the implementation. Then define identifications for these interfaces. These could be strings or integers or GUID's.
Then make a map in your application that maps the identifications to the interfaces, and fill the map with the correct implementations of the interfaces. In a C++ application (I'm not very skilled in C# yet) this could work like this:
std::map<std::string,IInterface> appInterfaces;
appInterfaces["database"] = new OracleDatabaseModule();
appInterfaces["userinterface"] = new VistaStyleUserInterface();
Make all modules go to this central registry whenever they want to use one of the modules. Make sure they don't access the modules directly, but they only pass via the registry. E.g.
MyModule::someMethod()
{
IDatabaseInterface *dbInterface = dynamic_cast<IDatabaseInterface *>(appInterfaces["database"]);
dbInterface->executeQuery(...);
}
If you now want to change the implementation for an interface in the application, you can simply change the entry in the registry, like this:
IInterface *iface = appInterfaces["database"];
if (iface) delete iface;
appInterface["database"] = new SqlServerDatabaseInterface();

Related

Class visible only to shared project?

I want to separate platform-independent logic of my C# program into a shared project. Now I would like to hide repositories, service classes and such from my platform-specific projects. What access modifier can I use? internal doesn't seem to work, as they are compiled into the same executable (I think) and I don't want to go tag all my classes with InternalsVisibleToAttribute.
Is there a way to make classes in my shared project invisible to my platform-specific code?
There's only one place where you need to know the real type you're trying to instance - the platform provider. Everyone else should just use the interfaces that are platform-invariant.
All the platform-specific implementations can then be private or internal for all you care - you just need to ensure the provider has access. Your application will use the platform-specific provider to get the platform-specific instances, while only ever using the platform-invariant interfaces.
As for "being compiled into a single executable", that's not really important. Most likely you care entirely about compile-time checking, and that's still present regardless of how the final executable is packaged. There's some restrictions on reflection in a partial trust environment, but by that point you shouldn't care - you're only in it for the compile checks, not the runtime safety.
No, there is no such feature in C#. If you consider marking every other project with InternalsVisibleToAttribute an option, that would do the trick.
If possible, you could split off those other files (repositories, service files) to another assembly, which is not included in your shared project.

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.

Modular application architecture and Castle Windsor

I'm developing a .Net desktop app that interacts with scientific instruments. There are a number of variations of this instrument, each with different features, components, etc, so I've come up with a plugin/modular architecture where a "module assembly" contains all of the necessary business logic, UI, etc. to interact with that hardware component/feature.
Currently I have one solution that contains everything - the "core" application project, common libraries, plus the "module" projects. The idea is that we install the whole lot to a customer site (rather than cherry-picking which DLLs they need), and "activate" the relevant modules using a config file that contains a list of required modules.
The main application project loads the modules using Castle Windsor, using an AssemblyFilter and a custom InstallerFactory. It searches each module assembly looking for a class implementing IWindsorInstaller and decorated with a particular custom attribute (which has a property containing the module name). The module's installer will only be run if the attribute's module name is one of those requested. These installer classes are responsible for registering everything needed by that module with Windsor (business logic, views, view models, etc.).
This solution works fine in my proof of concept, however I can see a scenario where two or more modules are functionally very similar, and will therefore need to share common code. Let's say I have projects "ModuleA" and "ModuleB", and their Windsor installers registers the same IFooService class in project "ClassLibraryX". The app will fall over because IFooService has been reigstered twice, and Windsor won't know which one to resolve when requested by a constructor.
What's the best way to handle this? Thoughts so far:-
Find out if a particular component has already been registered with Windsor. This feels hacky (if possible at all)
Register components using a name, but how do I request a named instance with constructor injection?
In each module project create a new interface, such as public interface IModuleAFooService : IFooService, and register/use this throughout the project (rather than IFooService).
Any thoughts?
Edit: in fact Windsor won't fall over when it tries to resolve IFooService. It will fall over when the second module attempts to register the same interface/concrete implementation!
The way I see it, you have a couple options. I think you have two main issues. The first is that you are installing the shared interface twice (or more than that). The second is that you could have two different versions of the shared interface.
For the first issue, I would separate out the shared interfaces into their own assembly. Inside that assembly, I would have an installer that is scoped to that assembly. Then, you can tell Windsor to install that shared component and it knows how to wire itself up.
For the second issue, you have two options (as I see it). First option is that you keep your shared components backwards compatible. Second option is to isolate you runtime (through app domains or processes).
Can you not provide some meta-data for the plugin, i.e give each plugin implementation a name attribute which can be used by windsor to identify which of the implementations you want?
I have not used Castle too much recently but I am sure it did have the notion of named Bindings/Registrations, so you could use that as a way to distinguish things, if that is not going to be possible and there is no other meta data you can think of using which would make it less ambiguous for Windsor, then I would just opt with your 3rd option.
Having just read your 2nd option again (after writing the above) that seems the best option, I cannot remember EXACT syntax but in most DI frameworks you do something like:
var instance = Get<IMyInterface>("Named This");
There will be loads of syntax examples on their documentation somewhere, but you will need to know the name on both the Windsor side to register it AND on the client side to request it.
Named instances are ok. You can define dependency on concrete named service via DependsOn(Dependency.OnComponent("paramName", "serviceName")) method in fluent configuration.

Changing winform app for specific clients

I have a winforms app. I give it to three clients and each one wants a small tweak or customization specific just to them. To accomplish this, I'd have to keep a separate version just for each client. I may wind up having many versions doing it this way. I thought dependency injection would be how to handle this but I hear you have to register your dependencies in the main method and you'd still have to add a reference to each clients DLL so I'd still need different versions. What is the preferred object oriented way to handle this? Any better ways to handle this?
You can use a Plug-in patten to load assembly at runtime: (from link)
Separated Interface (476) is often used when application code runs in multiple runtime environments, each requiring different implementations of particular behavior.
Most DI frameworks provide this functionality. You can search at get lots of Examples for framework you choose - if you don't want to roll your own.
Ninject
MEF
You can use a configuration file to configure your DI container, so that you can reuse the same binaries with different configuration files to implement the different customizations. But you need to be sure that you thoroughly test all of your different configurations. Slightly different versions of the same application are not trivial to maintain without causing unanticipated breaks.
Depending on the nature of the customixations, you might be able to capture all relevant modifications into a distinct part of the project (as opposed to keeping them spread all-over the project). If you can (e.g. a filering functionality is provided by the client), you can then load a DLL dynamically (e.g. based on a config file) and allow the functions in the DLL to perform the necessary functionality that accomplishes the customization (based on parameters provided by the main code).
This way you provide pre-defined hooks to your code that can be changed dynamically (even if only to load the dlls at startup time) as per the need of the client. You can separate these DLLs into multiple ones if there are distinct features that the clients want to change, but not necessarily all of the clinets all of the features. Then you can provide a "default" version of the DLLs.
Who develops the hooks is dependent on your setup with the clients.
Make sure you provide adequate documentation on how these hooks supposed to work -- even if you end up developing them.

System with plugins in C#

I have to develop a system to monitor sensor information, but many sensors might be added in the future.
That said, the idea would be to develop a system that would consist of the application skeleton. The sensors (as each of them has its communication and data presentation characteristics) would be added as plugins to the system.
How would I code this on C#? Is it a case of component-driven development? Should I use dynamic libraries?
There are a huge number of ad-hoc plug-in systems for C#. One is described in Plugin Architecture using C# (at The Code Project). The general approach is that the host application publishes an assembly with interfaces. It enumerates through a folder and finds assemblies that define a class that implement its interfaces and loads them and instantiates the classes.
In practice you want to do more. It's best if the host application defines two interfaces, an IHost and an IPlugIn. The IHost interface provides services that a plug-in can subscribe to. The IPlugIn gets constructed taking an IHost.
To load a plug-in, you should do more than simply get a plug-in. You should enumerate all plug-ins that are loadable. Construct them each. Ask them if they can run. Ask them to export APIs into the host. Ask them to import APIs from the host. Plug-ins should be able to ask about the existence of other plug-ins.
This way, plug-ins can extend the application by offering more APIs.
PlugIns should include events. This way plug-ins can monitor the process of plug-ins loading and unloading.
At the end of the world, you should warn plug-ins that they're going to go away. Then take them out.
This will leave you with an application that can be written in a tiny framework and implemented entirely in plug-ins if you want it to.
As an added bonus, you should also make it so that in the plug-ins folder, you resolve shortcuts to plug-ins. This lets you write your application and deliver it to someone else. They can author a plug-in in their development environment, create a shortcut to it in the application's plug-ins folder and not have to worry about deploying after each compile.
Managed Extensibility Framework (MEF) is what you need here. You could also use a dependency injection container, but that's a bit not what you'd expect, though a perfectly viable solution in itself.
Each sensor should implement a standard interface so that routines that handle lists of sensors can treat them in a standard manner. Include a ID field in the interface that is unique too each type of sensor so you can handle special cases.
Look at the Reflection API to learn how to scan a directory of .NET Assemblies and look inside them.
Each assembly should have a factory class that it's job is to return a list of sensors that are in that assembly. I recommend that you make it a subroutine not a function and passes it a list that that it appends too. SensorDLL1 appends 4 sensors to the emptylist, SensorDLL2 appends 8 sensor to the list which now has 12 sensors and so on. This approach is the most flexible in the long run.
You will either have to make up a naming convention to find the factory class or use an attribute. Note I don't recommend just scanning the assembly for everything that implements your sensor interface as you could have code inside the factory that controls which sensors are available. This is useful for licensing.
Depending upon the Sensors themselves, this sounds like you would need to define a single interface which all Sensors will implement. Your main "application skeleton" will then work against the ISensor interface and need not concern itself with the concrete implementations of each of the Sensor classes/objects/components.
Whether each Sensor is simply a class within the same project, or a separate assembly is up to you, although if they are separate assemblies, you'd need a way to load these assemblies dynamically.
Some references which may help here are:
Command Pattern Design Pattern:
- http://en.wikipedia.org/wiki/Command_pattern
Observer Pattern Design Pattern:
- http://en.wikipedia.org/wiki/Observer_pattern
Dynamically loading assemblies:
- http://www.divil.co.uk/net/articles/plugins/plugins.asp
Hope this helps.
We once made a plug-in system in a school project of ours in 2006, Socio. You can find the code here and here.
The basic lesson learned was that it is very simply to dynamically load code in C#. If you just have a plugin DLL and an application which adheres to an interface of yours and links against a common DLL in which that interface exists, it just works™.
In essence, it is what plinth described in his answer.
Take a look at:
Composite UI Application Block
and Smart Client Software Factory
Its a very old post but still i thought it would be useful for someone to appPress.in where in we have developed a framework with plugin functionality. here we allow plugin to modify the UI of core application Horizontally and Vertically, add its own Pages, hook into events like Init, OnClick and OnChange.

Categories

Resources