I've got main project, and a series of dll's that have specific implementations of some interfaces as well as view\viewmodels, etc. I use {ImportMany] to get them all with some metadata, which allows me to choose one, which gives me a reference to the specific implementation of ISystem.
I'd like to get the only specific implementation of IDisplay from whatever dll the ISystem is chosen from, which I marked with [Export("SomeDisplay", typeof(IDisplay))]
So far, the only thing that I can find that looks like it might work is GetExports(ImportDefinition), but I don't understand how to create an ImportDefinition that would work, as it seems to want a specific contractname, which isn't known until runtime.
Of course since I'm still a MEF n00b, it's a good bet I'm doing it wrong :D
So, if GetExports is the best way, how can I make it work? Or is there a better way I should be using?
Thanks!
You need to look into providing metadata along with your MEF exports.
See these articles and blog posts for details:
Building Hello MEF – Part II – Metadata and why being Lazy is a good thing.
MEF for beginner - Part 8 - Metadata
Providing metadata to your MEF exports
Related
This request might sounds a little bit odd, but application-performance and maintenance is cruciual, so I'm really looking for something as described.
Because I'm not sure if the 3 words are enough to explain what I'm looking for, here's an example:
I use IoC a lot, especially if I have dyniamical behaviours, which is often the case.
It's a very easy and frankly cool technique to have a loose coupled application.
But the freedom comes with a price of a higher performance-cost, compared with a "hard wired" solution.
Normally this is not a too big issue, but in the current case, it is.
So what I'd like to have is a feature which works like an IoC, but of course with a hard-wired .cs-file, instead of an "generated at runtime" Container.
Like if I need all implementations of IBehaviour, I'd get an output such as "behaviours = new List { impl1, impl2, ... }, instead of behaviours = Container.GetAllInstancesOf()
Hope it's clear what I'm looking for and that something like this exists.
And if not: What would be the way to implement this feature? Only way I can imagine is a VisualStudio-Plugin which reflects a compiled dll and with the help of custom attributes can write a .t4-file.
Cheers!
I don't know if what you're looking for exists, but I implemented something which may serve as an example to get you started: a T4 typed factory generator. Basically you mark your class with an attribute and T4 will generate a factory implementation based on a factory interface (if it doesn't exist, the script will generate the factory interface as well).
You can look at the code at https://github.com/PombeirP/T4Factories, and a NuGet package is available at https://www.nuget.org/packages/T4Factories/.
Hope this helps.
Are you sure that ioc has:
higher performance-cost, compared with a "hard wired" solution
?
Comparing the performance, you can see that:
singleton registration takes 68ms, without container 78ms
transient (a new instance is created every time) takes 66ms, without container 88ms
Moreover, now IoC container is very small, for example DryIoc has no more than 2500 lines of code including comments.
Update:
DryIocZero supports compile-time generation of factories with all registered dependencies (I am a maintainer).
I'm currently working on a compile time IOC container for .Net which should have almost zero overhead (for many cases it generates practically the same code as you would write yourself). Try it out at https://github.com/YairHalberstadt/stronginject.
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.
This is similar to a few other threads i have found, but I haven't found the answer I need yet. I would appreciate a direct answer, even if it is "no, you can't do that".
Is there a way to use one block of code if a class/type exists and another if it doesn't. The result would be the same as using preprocessor directives but without the need to #define and manually comment or un-comment something in a file.
This may be a special use-case. I'm not sure. I'm working in an environment where sets of files can be installed, or not, before anything is compiled. So someone could buy a plugin which gets "installed" (files added to the project) which makes classes/types available for use (like extending an API). I need to provide a workaround if someone doesn't have one of our other plugin packages. I hope that makes sense.
It just wouldn't be user-friendly to ask someone to open up one of our files, if they have another plug-in, to un-comment a preprocessor directive, unless we have to.
e.g. I know this doesn't work because it only tests boolean if #define is used, but it illustrates what I am trying to do...
#if SomeType
SomeType.DoSomething();
#else
DefaultWay.DoSomething();
EDIT: I added this as a C# feature suggestion. Please vote here:
http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2297494-add-type-testing-as-preprocessor-directive
I don't see how reflection would be able to do this, but I am new to C#, so examples using relection, if it is possible, would be great.
Instead of using pre-compiler statements (which I don't know if they would work anyway if the client didn't have to recompile after installing your plug-in), I would suggest querying the assembly and trying to instantiate an instance of the class by string as seen here:
C# - Correct Way to Load Assembly, Find Class and Call Run() Method
Assembly assembly = Assembly.LoadFile(#"C:\dyn.dll");
Type type = assembly.GetType("TestRunner");
if (type != null)
//Do Something
Editing to show Activator call
if type is not null then use this to create an instance of the type you want.
var obj = Activator.CreateInstance(type);
You could define interfaces for your types/services that your evaluation-provided code supports, but doesn't provide. Then you could use a plugin framework like MEF, which is built into the .Net Framework (v4.0).
MEF will do the reflection and assembly enumeration for you. You just have to define simple extension points in your code.
Here is some basic documentation for MEF. It might be specific to the Codeplex version of the code (not sure) but it shouldn't be too old, and should give you a good idea of how it works:
http://mef.codeplex.com/wikipage?title=Guide&referringTitle=Documentation
Alternative ideas
You might want to solve this with licensing rather than distribution.
You're going to have to solve the licensing problem anyhow, so you can collect money from users, and so you can sue people who grievously violate your copyright.
If your code is worth distributing, you won't be able to prevent distribution. Piracy is not preventable.
And most licensed code I've used recently have full-featured but timed trials, and phone home. They install all the code, but simply disable parts of it if they aren't licensed. It is hard for someone to know if they want to pay for your advanced features if they can't try them out :)
Do you really care what is present at compile-time, or at run-time? You might be able to use a Factory pattern to encapsulate the logic for which class to instantiate assuming that polymorphism is possible (they both share an interface or base class).
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 adding comments to some csharp code, and i'm using the xml language provided by .net (or something). i have an interface, and some implementing classes. i have one method in the interface, and it has a comment. in the implementing classes there is no comment on the implementing method.
when one does it like this in java, javadoc automagically uses the interface comment when generating documentation. however, now that i build my project, i get the warning (transalted from swedish, sorry) "the xml comment for the visible type or member bla.blabla.blablabla() is missing (cs1591)". this is only a warning, so not so bad. but!!! it means no xml file was output, so i can't use sandcastle to generate a chm document file, which is my real goal here.... googling the error coded gave nothing :(
do i really have to copy the method comment to all implementing classes? that's like.... code duplication D: is there no way to get the behavior java offers?
I don't know of any way of getting it to happen at XML file generation time, but GhostDoc may well save you from performing the copying manually. I can't say I've used it myself though.
I agree that it would be a valuable feature... particularly if the base class (or interface) documentation changes after the derived classes have been implemented and documented.
You do have to copy the interfaces comments to the implementing class. Generally this is a good thing as the two comments should ideally be different - my opinion (and practise) on this can be summarised as the following:
Interface Comments - Explains what the method/property/etc is supposed/expected to do but should generally not proscribe how any specific implementation should behave
Implementing Class Comments - Explains what the method/property/etc actually does and may include some details of how this is done (typically in <remarks>)
VSdocman can resolve missing XML comments from implemented interfaces automatically when it generates documentation. Moreover, like GhostDoc, it can also explicitly copy inherited comments to the implementing method. Unlike Sandcastle, it's not free.
Well i dont know about Java but Sorry you will have to copy the interface's comments in the implemented class. here is no inbuilt way of doing it...
And yeah consider the suggestion given by JonSkeet