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.
Related
I have a C# WinForms application in Visual Studio 2010 that is used by two different customers. The basic functionality of the application is the same for each customer, but certain lines of code (names of stored procedures, resources, certain behaviors) are different between versions. So far, I have kept the application in the same project, and used preprocessor directives when building/publishing to switch between which deployment to use. However, the scope of the project has grown to a point where this is no longer feasible.
Since so much of the code is shared, I'm trying to avoid duplicating source code files. I'm wondering what the best approach is to maintaining an application that requires different versions to be deployed simultaneously.
Use interfaces to define your classes. Having an interface means that you can have multiple implementations of the same interface, one for each of the clients. This will require you to analyze your existing codebase and identify logical separations in your code where these interfaces can be defined.
You then have the ability to load an interface as needed based on the client. You could, for example, do this via configuration. Based on a configuration value you load Implementation1 or Implementation2. There are many, many ways to accomplish this particular bit. You should read up on dependency injection, inversion of control and have a look at tools like Ninject, Autofac, Unity.
It may actually be difficult at first considering how you have been using preprocessor directives but seeing as how your application is growing, you will need this refactoring to happen. Keep in mind that if you do not do it now, this refactoring will be a lot more expensive later as your application becomes more complex.
The different functionality should be a part of the application's architecture. If you need different functionality for different customers, abstract it away - create an interface that wraps up the behaviour, then implement it in two different ways in two different assemblies. Then (depending on your deployment mechanism), you can ship your app with either one DLL or the other. To avoid having to recompile, add references, etc, you can use Dependency Injection frameworks such as Ninject, Castle Windsor, MEF etc. That's a "plugin-like" architecture, if code is sufficiently different.
If you're talking about text, colours, basic differences, they should simply not be hard coded but instead data-driven. If your app is internet-connected, it could download the appropriate settings when the user logs in. Else, something to indicate the text/colours/behaviour could be put in a config file specific to the customer. You can use config transforms to simplify that process.
You might be able to separate some of the differences by using resource, configuration, or property files of some kind. By this, I mean you store some kind of value in the file, such as the name of the stored procedure to use in a particular situation. Then your code reads the name from the file and runs it. You can change the values in the file without needing to rebuild your code for each deployment.
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 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.
I'm currently working on a large real-time OLAP application. All data are hold in RAM (a few gigabytes) and the common tasks involve brute scanning over the large quantity of that data (which is fine). The results of processing are exposed via a Web service (singleton/multithreaded) and presented using Silverlight-based client.
The problem is that various customers need different functionality/algorithms and I don't know how to provide extensibility on the server-side. For the client side (Silverlight) I can use MEF/Prism, but I'm not sure what would be a good approach to tackle this problem on the server.
Please note that ideally other web-services should have a direct access (i.e. without marshaling) to the data of the main/current service which holds the large data model.
Are there any:
a) frameworks/libraries
b) patterns
c) good pracitces
which would help me to modularize the application and make the selection of desired modules and their deployment relatively easy?
Sounds to me like Dependency Inversion is required: isolate logical parts of the system (algorithms, etc) by defining interfaces, then use a DI / IoC framework to load the desired implementation at runtime (or on application start, etc).
I haven't used Ninject, but plenty of people love it, so you could try that; there's also Spring.Net.
Good Practices:
Ensure you have clear precise logging so you know what's being used and when.
Think about whether you want a 'default' implementation to load if the desired one fails, or whether you deliberately want to fail so that the wrong data isn't returned by mistake (such as the use of a different algorythm).
I've found that using attributes to decorate injectable modules is really helpful (especially in a web-based system that you don't have immeadiate access to) one reason for this is that you can build pages or controls that list all the known / available implementations at runtime.
You can also use the attribute approach to build a UI that lets users select which one they want; I use it for an open source web-application framework I built: http://www.morphological.geek.nz/Morphfolia/Capabilities/AttributeDriven.aspx
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.