PluginAssemblyAttribute confuses new plugin developers.

Developer
Jun 25, 2011 at 12:40 AM
We've noticed that new plugin developers (often being people that haven't coded much before) have been confused about all of the setup required to create a new plugin. One of the steps is adding the PluginAssemblyAttribute. I can't tell that this really needed. Was it used at one point to improve performance?

Here's the code that checks for the attribute:
  var attributes = asm.GetCustomAttributes(typeof(PluginAssemblyAttribute), false);
if (attributes.Length == 0) return// don't bother with a dll unless it marks itself as a MW plugin assembly
Developer
Jun 25, 2011 at 5:21 PM
Hate to be a pain about this, but have we evaluated System.Addin?
http://www.codeproject.com/KB/dotnet/AddInModel.aspx

It provides isoloation (plug in crashes, app should not), the ability
to reload a plug-in, and interface versioning The Hydromodeler has
issues with reloading models, and System.AddIn is one solution
(Application Domains is the other).

DotS has a well defined interface, so that part of the design is done.

http://stackoverflow.com/questions/835182/choosing-between-mef-and-maf-system-addin
http://clraddins.codeplex.com/

On Fri, Jun 24, 2011 at 5:41 PM, [email removed] wrote:
> From: mudnug
>
> We've noticed that new plugin developers (often being people that haven't
> coded much before) have been confused about all of the setup required to
> create a new plugin. One of the steps is adding the PluginAssemblyAttribute.
> I can't tell that this really needed. Was it used at one point to improve
> performance?
>
> Here's the code that checks for the attribute:
>
>   var attributes = asm.GetCustomAttributes(typeof(PluginAssemblyAttribute), false);
>
> if (attributes.Length == 0) return; // don't bother with a dll unless it marks itself as a MW plugin assembly
>
> Read the full discussion online.
>
> To add a post to this discussion, reply to this email
> ([email removed])
>
> To start a new discussion for this project, email
> [email removed]
>
> You are receiving this email because you subscribed to this discussion on
> CodePlex. You can unsubscribe or change your settings on codePlex.com.
>
> Please note: Images and attachments will be removed from emails. Any posts
> to this discussion will also be available online at codeplex.com
Developer
Jun 27, 2011 at 8:28 PM

I'm open to exploring System.Addin and MEF, but initially haven't moved in that direction based on the follow premises:

1) The plugin developer experience should be simplified

2) Our plugin developers aren't evil (generally, they will make mistakes but we don't need to restrict them)

3) Isolation boundaries come at the expense of performance, and potentially, complexity

 

On the other hand, we might just migrate to one of these frameworks, because

1) The value of DotSpatial is not in it's ability to provide "yet another plugin framework"

2) Microsoft's code is better tested than ours, and using it means less maintenance for us

3) Those options are already included in  .Net 4

 

I suspect that the situation we are was designed to make migrating plugins from MapWindow 4.x straightforward, so we will want to keep that audience in mind.

 

Can you refer me to the Hydromodeler issue item? I don't immediately understand how System.AddIn is a solution, there.

Developer
Jun 27, 2011 at 8:40 PM

Back on the original topic, I did a few performance tests, and noticed that removing this check for a custom attribute cut load time for the plugins in half. I was testing with about 47 files that didn't have a large number of classes per file, but my analysis is that this attribute doesn't help performance.

Here's some of the testing code as a sample:

            var sw = Stopwatch.StartNew();
            foreach (string path in files)
            {
                UpdateAssembly(path, areApplicationExtensions);
            }
            sw.Stop();
            Trace.WriteLine(sw.ElapsedTicks);
Developer
Jun 27, 2011 at 8:59 PM

I recall that the original intent of using an assembly attribute was so we would not have to run into so many exceptions trying to load DLLs that are not plugins but are just support libraries for plugins. I would be curious how other plugin frameworks handle figuring out which DLL is a plugin.

It seems like now is better than later for us to evaluate whether one of these frameworks would be better than the custom solution we are already working with.

I would second the caution about isolation boundaries being potential performance bottlenecks - we certainly don't want to waste time marshaling like we have to when calling into the MW4 ocx.

I don't think there is much of value in terms of support for migration from MW4 in the current plugin strategy.

Developer
Jun 27, 2011 at 9:03 PM
Questions:
1) Did you run in Release or Debug?
2) signed or unsigned assemblies?
3) GAC or Non-GAC

I've found debug can have a large penalties,
If you care about performance, put the code in the GAC.
And it used to be you should look at using sealed classes. Not sure if
that it true anymore.

On Mon, Jun 27, 2011 at 1:40 PM, [email removed] wrote:
> From: mudnug
>
> Back on the original topic, I did a few performance tests, and noticed that
> removing this check for a custom attribute cut load time for the plugins in
> half. I was testing with about 47 files that didn't have a large number of
> classes per file, but my analysis is that this attribute doesn't help
> performance.
>
> Here's some of the testing code as a sample:
>
>             var sw = Stopwatch.StartNew();
>             foreach (string path in files)
>             {
>                 UpdateAssembly(path, areApplicationExtensions);
>             }
>             sw.Stop();
>             Trace.WriteLine(sw.ElapsedTicks);
>
> Read the full discussion online.
>
> To add a post to this discussion, reply to this email
> ([email removed])
>
> To start a new discussion for this project, email
> [email removed]
>
> You are receiving this email because you subscribed to this discussion on
> CodePlex. You can unsubscribe or change your settings on codePlex.com.
>
> Please note: Images and attachments will be removed from emails. Any posts
> to this discussion will also be available online at codeplex.com
Developer
Jun 27, 2011 at 9:18 PM
If we don't need the isolation, the MEF may be the answer

And there is alwasys Lazy<T>


On Mon, Jun 27, 2011 at 1:59 PM, [email removed] wrote:
> From: vatavian
>
> I recall that the original intent of using an assembly attribute was so we
> would not have to run into so many exceptions trying to load DLLs that are
> not plugins but are just support libraries for plugins. I would be curious
> how other plugin frameworks handle figuring out which DLL is a plugin.
>
> It seems like now is better than later for us to evaluate whether one of
> these frameworks would be better than the custom solution we are already
> working with.
>
> I would second the caution about isolation boundaries being potential
> performance bottlenecks - we certainly don't want to waste time marshaling
> like we have to when calling into the MW4 ocx.
>
> I don't think there is much of value in terms of support for migration from
> MW4 in the current plugin strategy.
>
> Read the full discussion online.
>
> To add a post to this discussion, reply to this email
> ([email removed])
>
> To start a new discussion for this project, email
> [email removed]
>
> You are receiving this email because you subscribed to this discussion on
> CodePlex. You can unsubscribe or change your settings on codePlex.com.
>
> Please note: Images and attachments will be removed from emails. Any posts
> to this discussion will also be available online at codeplex.com
Developer
Jun 28, 2011 at 12:21 AM

I ran the test in Debug mode with non-GAC assemblies. There's no sense in thinking this was a foolproof test, but it demonstrated that reflecting on an assembly to get a custom attribute takes time.

You will run into the BadImageFormatException when trying to load non-.Net dlls; Because that step happens prior to checking the loaded assemblies to see if they have a particular attribute, no time is saved by checking for the attribute.

A case when checking for the assembly level attribute might help, is when you have a valid .Net assembly with many classes, none of which are decorated with the Plugin attribute.

Coordinator
Jun 28, 2011 at 5:27 AM

All I will add is that anything we can do to simplify setting up a new plugin is a big huge PLUS.

- Dan
--------
Daniel P. Ames Ph.D.
Idaho State University Dept. of Geosciences
dan.ames@isu.edu
--------
Sent from my Droid

On Jun 27, 2011 6:22 PM, "mudnug" <notifications@codeplex.com> wrote:
> From: mudnug
>
> I ran the test in Debug mode with non-GAC assemblies. There's no sense in thinking this was a foolproof test, but it demonstrated that reflecting on an assembly to get a custom attribute takes time.You will run into the BadImageFormatException when trying to load non-.Net dlls; Because that step happens prior to checking the loaded assemblies to see if they have a particular attribute, no time is saved by checking for the attribute.A case when checking for the assembly level attribute might help, is when you have a valid .Net assembly with many classes, none of which are decorated with the Plugin attribute.
>
>
Developer
Oct 26, 2011 at 12:16 AM

For those following this thread, we've migrated Tool, DataProviders, and Extensions to use System.ComponentModel.Composition. LayerProviders will be migrated as well at some point.