I hope this question makes sense. Basically, I am looking for a set of guidelines, or even a tutorial, that will show how to make an application that can easily add and remove "modules" or "add-ins"
For example, in Microsoft Office, you will commonly see programs that you can download and install and they will just add an extra tab into Microsoft Word (for example) that will implement some new feature.
I have several applications that use basically the same data source, and I'd like to consolidate them and also leave open the possibility of adding more functionality in the future without 1. Requiring a brand new install and 2. Tweaking every piece of my code.
I'm looking for a place to start, mostly.
Thanks in advance.
**
Edit: To elaborate a little more...
The thing I have in mind specifically is an application that accesses a large set of data that is stored in text files and uses some of the data to create a few graphs and maybe some tables. I'd like the ability to add different graphs in the future using the same data. So, you can click Button_A and generate Graph_A, then a few weeks later, you can click Button_B and generate Graph_B.
It would be really nice if I could come up with a way that only required reading the data from the file(s) once, but I know that would involve having to adjust my DataReader class a bit.
One place to start would be to define an interface for your future modules, and build a utility that scans all the dll's therein, looking for classes that implement said interface.
Once you've found supporting classes you can create instances at runtime and add to your application. That's a common idiom in .NET for supporting "plug-ins"
The Activator class is a common way to create instances from a Type at runtime.
http://msdn.microsoft.com/en-us/library/system.activator.aspx
It's hard to give more details without more info in your question. Can you elaborate a bit?
Take a look at the Composite Application Library from Microsoft.
It is aimed at WPF but you could get some ideas from there.
As Adam said, the first thing to do is define the interface for your plugin modules - what can they expect to receive from the container, and what methods must the container be able to call?
As far as the container itself goes, I'm partial to MEF as a location technology; you can create catalogs and re-compose the system when new DLLs are added. I've built a similar system to this for parsing dissimilar files, and the composition capabilities of MEF are awesome for runtime discovery.
Related
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.
I have a fairly simple console app that monitors an exchange mailbox, picks particular emails out, and updates a couple of databases based on the contents.
I would like to implement a couple of similar systems. While it would be very simple to duplicate this system, I am looking at a more sophisticated solution - mainly an intellectual exercise, a learning exercise.
I would like to build a core application that pulls template information periodically from a DB; this information would tell the app that is has to monitor a given mailbox for emails with given characteristics at a particular interval.
I envision creating a master template (assembly) with some virtual functions (pre-processing, process items, archive items, send notifications etc). In turn, I'd create any number of templates that implement the interfaces in the master template, but the functionality could differ wildly in each case, one may update a database, while the next might store something in a file system.
My first question is whether this is a sensible implementation?
My second question is how to dynamically reference each template, and how would I call the methods of these templates at the appropriate time?
If I were to extend my Templates project, adding a new class for each new template required, I'd overcome the problem of dynamically referencing the templates. But if I wanted to keep them in separate assemblies.. Is there a way to just drop them into the project? Don't forget, the templates will be listed in a DB, so the app will be aware of them, but how to make use of them...
UPDATE:
I've figured how I can dynamically reference each template class; it requires me to supply the Assembly-Qualified Name to GetType:
I've tried to dynamically generate the template in the main app:
string aqn= "MasterTemplates.TestTemplate, TestTemplate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
MasterTemplate mt = (MasterTemplate)Activator.CreateInstance(Type.GetType(aqn));
So if I keep updating my MasterTemplates project, adding in new classes as necessary, I can achieve what I am aiming for. However, how can I handle different template assemblies?
In the meantime, I'm shortly going to look at DBM's suggestion of the Managed Extensibility Framework.
Conclusion:
I don't have the time to fully investigate MEF; though it's overkill for my current needs, it looks extremely promising. And I haven't figured how to easily develop and use different assemblies for different templates - instead I am keeping all templates in one assembly, which I will have to recompile and up-date each time I require a new template. Not quite as sophisticated as the MEF alternative, but simpler and suited to my current needs.
You could use MEF to dynamically load plugins. It's in-the-box in VS2010, and works great for dynamically loading assemblies.
When using activator with a string, use the Activator.CreateInstance(String,String) overload.
Alternatively you can create an instance of the type and use it like that:
Activator.CreateInstance(Type.GetType(templateName));
Short Version
I have an application which utilizes a plug-in infrastructure. The plug-ins have configurable properties that help them know how to do their job. The plug-ins are grouped into profiles to define how to complete a task, and the profiles are stored in XML files serialized by the DataContractSerializer. The problem is when reading the configuration files, the application deserializing has to have knowledge of all of the plug-ins defined in the configuration file. I'm looking for a way to handle the resolution of unknown plug-ins. See the proposed solution section below for a couple of the ideas I've looked into implementing, but I am open to just about anything (though I'd rather not have to reinvent the application).
Detail
Background
I've developed a sort of Business Process Automation System for internal use for the company I'm currently working for in C# 4. It makes exhaustive use of 'plug-ins' to define everything (from the tasks that are to be performed to the definition of units of work) and relies heavily on a dynamic configuration model which in turn relies on C# 4/DLR dynamic objects to fulfill jobs. It's a little heavy while executing because of its dynamic nature but it works consistently and performs well enough for our needs.
It includes a WinForms configuration UI that uses Reflection extensively to determine the configurable properties/fields of the plug-ins, as well as, the properties/fields that define each unit of work to be processed. The UI is also built on top of the BPA engine so it has a thorough understanding of the (loose) object model put in place that allows the engine to do its job, which, coincidentally, has led to several user experience improvements, such as, ad-hoc job execution and configure-time validation of user input. Again there is room for improvement, however, it seems to do its job.
The configuration UI utilizes the DataContractSerializer to serialize/deserialize the settings specified, so any plug-ins referenced by the configuration must be loaded before (or at the time of) configuration load.
Structure
The BPA engine is implemented as a shared assembly (DLL) which is referenced by the BPA service (a Windows Service), the Configuration UI (WinForms app), and a plug-in tester (Console application version of the Windows Service). Each of the three applications that reference the shared assembly only include the minimum amount of code necessary to perform their specific purpose. Additionally, all plug-ins must reference a very thin assembly which basically just defines the interface(s) that the plugin must implement.
Problem
Because of the extensibility model used in the application, there has always been a requirement that the config UI is run from the same directory (on the same PC) as the Service application. That way the UI always knows about all of the assemblies that the Service knows about so they can be deserialized without running into missing assemblies. Now that we are getting close to roll out of the system, a demand to allow the Configuration UI remotely on any PC in our network has come about from our network admins for security purposes. Typically this wouldn't be a problem if there was always a known set of assemblies to deploy, however, with the ability to extend the application using user built assemblies, there has to be a way to resolve the assemblies from which the plug-ins can be instantiated/used.
Proposed (potentially obvious) Solution
Add a WCF service to the Service application to allow the typical CRUD operations against the configurations which that instance of the service is aware of and rework the configuration UI to act more like SSMS with a Connect/Disconnect model. This doesn't really solve the problem so we would also need to expose some sort of ServiceContract from the Service application to allow querying of the assemblies it knows about/has access to. That's fine and fairly straight forward however the question arises, "When should the UI find out about the assemblies that the Service is aware of?" On connect we could send all of the assemblies from the Service to the UI to ensure that it always knows about all of the assemblies the service does but that gets messy with AppDomain management (potentially unnecessarily) and assembly version conflicts. So I suggested hooking into the AppDomain.AssemblyResolve/AppDomain.TypeResolve events to only download the assemblies that the client isn't aware of yet and only as needed. This doesn't necessarily cleanup the AppDomain management issues but it definitely helps address the version conflicts and related issues.
Question
If you've stuck with me this long I applaud and thank you, but now I'm finally getting to the actual question here. After months of research and finally coming to a conclusion I am wondering if anyone here has had to deal with a similar issue and how you dealt with the pitfalls and shortcomings? Is there a standard way of handling this that I have missed completely, or do you have any recommendations based on how you have seen this successfully handled in the past? Do you see any problems with the proposed approaches or can you offer an alternative?
I'm aware that not everyone lives in my head so please let me know if you need further clarification/explanation. Thanks!
Update
I've given MEF a fair shake and feel that it is too simplistic for my purposes. It's not that it couldn't be bent to handle the plug-in requirements of my application, the problem is doing so would be too cumbersome and dirty to make it feasible. It is a nice suggestion and it has a lot of potential, but in its current state it just isn't there yet.
Any other ideas or feedback on my proposed solutions?
Update
I don't know if the issue I'm encountering is just too localized, if I failed to properly describe what I am trying to achieve, or if this question is just too unreasonably long to be read in its entirety; but the few answers I've received have been subtly helpful enough to help me think through the problem differently and identify some shortcomings in what I am after.
In short, what I'm trying to do is take three applications which in their current state share information (configuration/assemblies) using a common directory structure, and try to make those applications work across a network with minimal impact on usability and architecture.
File shares seem like the obvious answer to this problem (as #SimonMourier proposed in the comments), but using them translates into lack of control and debugability when something goes wrong. I can see them as a viable short term solution, but long term they just don't seem feasible.
tl;dr, but I'm 90% sure you should take a look into MEF.
When I first saw it I was like "aah, another acronym", but you'll see it's very simple, and it's built in into .NET 4. Best of all, it even runs seamlessly on mono and it's a matter of less than an hour (including coffee break) between hearing about it and compiling hello worlds to get used with the features. It's really that simple.
Basically, you "export" something in an assembly and "import" it into another (all via simple attribute decorations), and you choose where to search for it (example, on the applications directory, plug-ins folder, etc).
Edit: what if you try to download and load (and possibly cache) plugins on-the-fly on configuration load?
I think that you could be overlooking a relatively simple solution that derives somewhat from the Microsoft web.config approach:
Have two sections in the config file:
Section 1 contains enough information about the plugin (i.e. name, version) to allow you to load it into an app domain.
Section 2 contains the information serialized by the plugin.
On loading the plugin, pass the information in section 2 and let the plugin deserialize it according to its needs.
Maybe you can divide this problem into two
administrator allow users to download one of predefined configuration (set of libraries) and MEF helps to inject required dependencies
each activity from user should pass through security proxy, plugin modules not allowed call BL directly. Proxy could match custom security attribute and allowed activities.
i.e.
[MyRole(Name = new[] { "Security.Action" })]
void BlockAccount(string accountId){}
[MyRole(Name = new[] { "Manager.Action" })]
void CreateAccount(string userName){}
[MyRole(Name = new[] { "Security.View", "Manager.View" })]
List<> AcountList(Predicate p){}
and allow for AD groups (some abstract description)
corp\securityOperators = "Security.*" //allow calls to all security manipulation
corp\HQmanager = "Manager.View" //allow only view access
corp\Operator = "Manager.*"
I'm not sure I completely understand the problem but I think this situation calls for "type-preserving serialization" - that is, the serialized file contains enough type information to deserialize back to the original object graph without any hints from the calling application as to what types are involved.
I've used Json.NET to do this and I can highly recommend the library for type-preserving serialization of object graphs. It looks like the NetDataContractSerializer can also do this, from the MSDN Remarks
The NetDataContractSerializer differs from the DataContractSerializer in one important way: the NetDataContractSerializer includes CLR type information in the serialized XML, whereas the DataContractSerializer does not. Therefore, the NetDataContractSerializer can be used only if both the serializing and deserializing ends share the same CLR types.
I chose Json.NET because it can serialize POCOs without any special attributes or interfaces. Both Json.NET and the NetDataContractSerializer allow you to use a custom SerializationBinder - in here you could put any logic regarding loading assemblies that may not yet be loaded.
Unfortunately, changing serialization schemes might be the "breaking-est" change to suggest because all your existing files will become incompatible. You might be able to write a conversion utility that deserializes a file using the old method and serializes the resulting object graph using the new method.
I wrote some classes that I use with many different projects.
For example, I use Library.Controls.FlatButton.cs almost in every project.
The problem is when I add this as an "existing item"; the class gets created/copied in my soultion folder everytime. And each time I edit/update the contents of that class, I have to update all the Library.Controls.FlatButton.cs files in every project folder.
I need to be able to edit a single source of FlatButton class and when I compile/build a project (that uses the class file) gets updated to the new version of that class.
Question 1: Is there a way to do this?
I know that I can gather all these classes in a library project (Library.Controls) and add it to each application solution as a dependency.
Question 2: Is this the only way to work from a single source of common library files? And if I do; will all the classes in the Library.Controls namespace get compiled with every application, even if I've only used this FlatButton class in the project?
Hope this is clear for you..
thanks
I'd rather go with the approach of the shared library and add them as references to your client project.
If you don't want to do this. You could add the file as "Link". In Add existing item, select Add as Link instead.
Yes, a class library is the way to go and yes, since the whole class library will be referenced from your applications, all the classes will be available to it.
However, the fact that all the classes are available is not a bad thing, since they're in a separate class library it won't make your applications harder to understand (since the amount of code in those applications will stay the same), it might just be that you use up a little bit more hard drive space, though if you really worry about that you could put the class library in the GAC so that all apps reference the same copy of the library, though you'd better research this first to make sure that it's suitable for you.
Alternative way is to add FlatButton.cs file "As Link":
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.