Multiple Plugins in single DLL MEF - plugins

Does MEF allow to host multiple Plugins in single DLL, so that i don't have to create a new class library for every new Plugin ?
Thanks.

You can have as many types in an assembly as you like, but whether or not those plugins would conflict is down to how you namespace and name them, and how they are exported.

Related

CRM could not load file or assembly to my project

I added a reference itextsharp.dll to my plugins project, when running my plugins using plugin-registration tool I get this exception:
Could not load file or assembly or one of its dependencies. The system
cannot find the file specified
I tried removing the ref and adding it again, cleaning and then adding it to my project from different places.
Is there restrictions in plugin registration tool about adding non crm dlls? why ? how to solve it?
This is not going to work - you cannot reference external assemblies from CRM plugins that are registered in database. If you want to do this, you will have to merge your external dll with your plugin assembly. You have to remember that adding assembly as reference is not automatically making your referenced assembly available for your base assembly, therefore if you register your plugin assembly in CRM, system is not going to "magically" find somewhere your external assembly (in your case - "itextsharp.dll"). If this is not Online system, you can add your assembly to GAC, or register all your assemblies on Disk instead of database (not recommended approach). If you want to register them in database, you will have to merge everything in one assembly using ILMerge for example.
You can't reference something in a plugin unless it's in the bin of the CRM.
To make it work you need to ILmerge your reference with the plugin. Install this package in your project: MSBuild.ILMerge.Task. Then build. It will work instantly. The package will merge everything in the bin after the build. So make sure every other references are marked "Copy Local = false". Otherwise, you'll have a crazy big assembly.
Finally, Microsoft released a solution for this. You can build a nupgk file and register dependent assemblies.
Here are the white paper and my post about this;
Microsoft : Microsoft White Paper
My summary: Here is the link

How can I import plugin projects from my workspace without specifying them?

I am developing an scripting environment for EMF and need to import the model plugin so that my script is able to use classes generated by the model, but in order to do that I need to explicitly add the plugin to my imports.
Can I do that automatically? Like adding all workspace plugins to my imports at runtime?
You can use DynamicImport-Package: * attribute in the bundle manifest to make all exported packages visible.
Note that packages imported via DynamicImport-Package are resolved every time a class from the package is needed. Consider selective dynamic import DynamicImport-Package: *;dynamic=mymodel or buddy policy as better alternatives.

What's the difference between Eclipse Packages and Plug-ins?

In Dependencies tab, I have a choice between plug-ins and packages.
What's the difference between them? For org.eclipse.compare, I have it in imported package and also in plug-ins.
I find the jar file in plugins directory, but I don't know where the package file of org.eclipse.compare is located.
In the export menu, it seems like that there seems to be only exporting to jar, not exporting a plugin or packages. How can I export packages?
ADDED
Based on this post - How to import a package from Eclipse? and shiplu's answer. This is what I came to understand. Please correct me if I'm wrong.
In eclipse, when I use come external class, I can use Quick-Assistant or Organize imports (Ctrl-Shift-O) to resolve the reference. Eclipse adds the package that contains the class in Imported Packages for the project that I'm working on. A package can contain multiple classes (types). Eclipse understands what plugin contains the package, and resolve the reference issues.
A plug-in (jar file) can contain multiple packages. By specifying a required plug-ins in the dependencies tab, we can reference all the packages (and classes in the packages) for all the java projects in the eclipse IDE.
And from my experience, I had to add all the dependencies in order to make headless RCP standalone (http://prosseek.blogspot.com/2012/12/headless-rcp-standalone.html).
An Eclipse plug-in is basically an OSGi bundle with additional plugin.xml file which Eclipse IDE understands and interprets.
So the answer to your question lies in the OSGi specification and the OSGi programming model, since, very simply put, Eclipse is an Application running on implementation of OSGi called Equinox.
OSGi is all about having modular applications and so it defines several levels of modularity.
One such level is a bundle-level (module-level) modularity and more fine grained level is the package level modularity.
So you can have your OSGi application (a set of bundles; eclipse is just that) which consists of db-bundle (which provides data store services), app-domain-bundle (which provides your application domain services) and remote-bundle (which exposes to the web your application via REST for example).
And then you say remote-bundle depends on domain-bundle which depends on db-bundle.
Which is all good, but cripples the inherent modularity OSGi provides, because you are basically restricting your application to specific implementations of db-bundle and remote-bundle i.e. to specific implementations of the services they provide.
Instead, you can establish the above dependencies not between bundles but between packages i.e. establish a service-level dependencies.
Then you say domain-bundle requires dbstore.service package to run, it doesn't care which bundle provides it it just needs an instance of this service to be able to work. So you can have multiple bundles providing implementations of the dbstore.service, and the domain-bundle can pick and choose at runtime what service to use.
It is really hard to explain OSGi concepts in just a several sentences, I'd really suggest you dig around the web on this and maybe even have a look at the OSGi specification.
Another way to explain it is to say that bundle/plug-in is a jar file with specific structure and metadata descriptors (MANIFEST.MF and plugin.xml), which describe its contents in Java language concepts - which java packages and services this specific jar contains and will expose to the OSGi runtime so that they can be consumed by other bundles. I.e. the bundle is the physical deployable entity while the descriptors are metadata about what actually is being deployed.
EDIT:
Package or Service-level dependencies also have some drawbacks, as Lii points out in the comments below, the main one being that it adds complexity and dynamics to the dependency model. Have a look at her or his comment below - it is worth reading!
You use Imported Packages when you want to use a specific package but do not care which plugin provides it. OSGI will choose one for you.
Eclipse plugins is something like extension to the IDE itself. But imported packages are actually packages that you'll use in your current project.
One is for development IDE another is for the project you are coding.

Regarding 'singleton:=true' in Manifest file

I have a plugin which at present doesn't have any extension points (neither does it extend any other plugin). To resolve a certain issue I have to create an extension-point for this plugin and an appropriate extension somewhere else.
When doing this eclipse forced me to set singleton:=true in the Manifest file. I know the reason why this parameter has to be set, but I wanted to know if there are any implications on the functioning of the plugin within the product by introducing this parameter.
Thank you.
"singleton:=true" means that bundle only have one version could exist in the OSGi runtime.
Eclipse automatically adds the flag due to you provide an extension point in your bundle. If there are two version of your bundles providing the same extension point(have the same identity, might different attributes or elements) would make things mess.
From the Book Eclipse plugin Development by Dr Alex Blewitt:
The clause
singleton:=true
is an OSGi directive, which means that only one version of this plug-in can be installed in Eclipse at one time.
For plug-ins which add dependencies to the UI, there is a restriction that they must be singletons. (This constraint is one of the main reasons why installing a new plug-requires the IDE to restart.)

Problem using in GWT project classes from other project/source folders

My project contains 2 source folder, one is generic J2EE application another is smartCleintGWT,
I want to use some already existing DTO classes from first source folder (src)
Note that class used on client side and on server side of GWT project!
When I do that I getting error
[ERROR] Errors in 'file:/C:/..Projects/Admin/DMX/src_console/com/ho/nod/client/AdminRPC.java'
[ERROR] Line 7: No source code is available for type com.dmx.synch.server.descriptors.DMXLicense; did you forget to inherit a required module?
Source is available obviously; is there any way to import all that into GWT?
PS In the future 2 source folder will be separated into 2 projects...I hope it wont be that complicated as well.
You can find in the good docs:
Modules can specify which subpackages
contain translatable source, causing
the named package and its subpackages
to be added to the source path. Only
files found on the source path are
candidates to be translated into
JavaScript, making it possible to mix
client-side and server-side code
together in the same classpath without
conflict. When module inherit other
modules, their source paths are
combined so that each module will have
access to the translatable source it
requires.
To add another subpackage add <source path="package"/> in your host file (*.gwt.xml). From the log you posted, it seems you have to add source from the com.dmx.synch.server package.
Most RPC problems are related to Serializablity of the DTO in question, can you need to ensure that the classes have default constructor and also check if the Module definition file i.e. .gwt.xml file has source element pointing to these packages.
GWT only looks for source code in the client package by default, so if you have added new packages you must specify this in your *.gwt.xml file.
Add something like: source path='your_top_dir' in XML format.