Free cookie consent management tool by TermsFeed Policy Generator

Changeset 2750


Ignore:
Timestamp:
02/04/10 12:20:43 (15 years ago)
Author:
gkronber
Message:

Prepared plugin infrastructure to work with versioned plugins and dependencies and added versioning to part of HL.GP plugins. #864 (Plugins should have an a version)

Location:
trunk/sources
Files:
5 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Core/3.2/HeuristicLabCorePlugin.cs

    r2591 r2750  
    3030  /// Plugin class for HeuristicLab.Core plugin.
    3131  /// </summary>
    32   [Plugin("HeuristicLab.Core-3.2")]
     32  [Plugin("HeuristicLab.Core-3.2", "3.2.0.0")]
    3333  [PluginFile("HeuristicLab.Core-3.2.dll", PluginFileType.Assembly)]
    3434  [PluginDependency("HeuristicLab.Common-3.2")]
  • trunk/sources/HeuristicLab.GP.Algorithms/3.2/HeuristicLab.GP.Algorithms-3.2.csproj

    r2566 r2750  
    8383  <ItemGroup>
    8484    <Compile Include="AlgorithmBase.cs" />
     85    <None Include="HeuristicLabGpAlgorithmsPlugin.cs.frame" />
    8586    <Compile Include="HeuristicLabGpAlgorithmsPlugin.cs" />
    8687    <Compile Include="OffspringSelectionGP.cs">
     
    186187set Outdir=$(Outdir)
    187188
    188 call PreBuildEvent.cmd</PreBuildEvent>
     189call PreBuildEvent.cmd
     190SubWCRev "%25ProjectDir%25/" "%25ProjectDir%25/HeuristicLabGPAlgorithmsPlugin.cs.frame" "%25ProjectDir%25/HeuristicLabGPAlgorithmsPlugin.cs"</PreBuildEvent>
    189191  </PropertyGroup>
    190192</Project>
  • trunk/sources/HeuristicLab.GP.Algorithms/3.2/HeuristicLabGpAlgorithmsPlugin.cs

    r2591 r2750  
    2626
    2727namespace HeuristicLab.GP.Algorithms {
    28   [Plugin("HeuristicLab.GP.Algorithms-3.2")]
     28  [Plugin("HeuristicLab.GP.Algorithms", "3.3.0.2728")]
    2929  [PluginFile("HeuristicLab.GP.Algorithms-3.2.dll", PluginFileType.Assembly)]
    3030  [PluginDependency("HeuristicLab.Common-3.2")]
     
    3232  [PluginDependency("HeuristicLab.Data-3.2")]
    3333  [PluginDependency("HeuristicLab.Evolutionary-3.2")]
    34   [PluginDependency("HeuristicLab.GP-3.3")]
    35   [PluginDependency("HeuristicLab.GP.Interfaces-3.3")]
    36   [PluginDependency("HeuristicLab.GP.Operators-3.3")]
     34  [PluginDependency("HeuristicLab.GP", "3.3")]
     35  [PluginDependency("HeuristicLab.GP.Interfaces", "3.3")]
     36  [PluginDependency("HeuristicLab.GP.Operators", "3.3")]
    3737  [PluginDependency("HeuristicLab.Logging-3.2")]
    3838  [PluginDependency("HeuristicLab.Operators-3.2")]
  • trunk/sources/HeuristicLab.GP.Algorithms/3.2/Properties/AssemblyInfo.frame

    r2341 r2750  
    2323using System.Runtime.CompilerServices;
    2424using System.Runtime.InteropServices;
    25 using HeuristicLab.PluginInfrastructure;
    2625
    2726// General Information about an assembly is controlled through the following
     
    3332[assembly: AssemblyCompany("")]
    3433[assembly: AssemblyProduct("HeuristicLab")]
    35 [assembly: AssemblyCopyright("(c) 2002-2008 HEAL")]
     34[assembly: AssemblyCopyright("(c) 2002-2010 HEAL")]
    3635[assembly: AssemblyTrademark("")]
    3736[assembly: AssemblyCulture("")]
     
    5453// You can specify all the values or you can default the Revision and Build Numbers
    5554// by using the '*' as shown below:
    56 [assembly: AssemblyVersion("3.2.0.$WCREV$")]
     55[assembly: AssemblyVersion("3.2.0.0")]
    5756[assembly: AssemblyFileVersion("3.2.0.$WCREV$")]
    58 [assembly: AssemblyBuildDate("$WCNOW$")]
  • trunk/sources/HeuristicLab.GP.Interfaces/3.3/HeuristicLab.GP.Interfaces-3.3.csproj

    r2566 r2750  
    8080  </ItemGroup>
    8181  <ItemGroup>
     82    <None Include="HeuristicLabGPInterfacesPlugin.cs.frame" />
    8283    <Compile Include="FunctionTreeIterator.cs" />
    8384    <Compile Include="IFunctionTreeSerializer.cs">
     
    119120set Outdir=$(Outdir)
    120121
    121 call PreBuildEvent.cmd</PreBuildEvent>
     122call PreBuildEvent.cmd
     123SubWCRev "%25ProjectDir%25/" "%25ProjectDir%25/HeuristicLabGPInterfacesPlugin.cs.frame" "%25ProjectDir%25/HeuristicLabGPInterfacesPlugin.cs"</PreBuildEvent>
    122124  </PropertyGroup>
    123125</Project>
  • trunk/sources/HeuristicLab.GP.Interfaces/3.3/HeuristicLabGPInterfacesPlugin.cs

    r2591 r2750  
    2626
    2727namespace HeuristicLab.GP.Interfaces {
    28   [Plugin("HeuristicLab.GP.Interfaces-3.3")]
     28  [Plugin("HeuristicLab.GP.Interfaces", "3.3.0.2591")]
    2929  [PluginFile("HeuristicLab.GP.Interfaces-3.3.dll", PluginFileType.Assembly)]
    3030  [PluginDependency("HeuristicLab.Core-3.2")]
  • trunk/sources/HeuristicLab.GP.Interfaces/3.3/Properties/AssemblyInfo.frame

    r2222 r2750  
    2323using System.Runtime.CompilerServices;
    2424using System.Runtime.InteropServices;
    25 using HeuristicLab.PluginInfrastructure;
    2625
    2726// General Information about an assembly is controlled through the following
     
    3332[assembly: AssemblyCompany("")]
    3433[assembly: AssemblyProduct("HeuristicLab")]
    35 [assembly: AssemblyCopyright("(c) 2002-2008 HEAL")]
     34[assembly: AssemblyCopyright("(c) 2002-2010 HEAL")]
    3635[assembly: AssemblyTrademark("")]
    3736[assembly: AssemblyCulture("")]
     
    5453// You can specify all the values or you can default the Revision and Build Numbers
    5554// by using the '*' as shown below:
    56 [assembly: AssemblyVersion("3.3.0.$WCREV$")]
     55[assembly: AssemblyVersion("3.3.0.0")]
    5756[assembly: AssemblyFileVersion("3.3.0.$WCREV$")]
    58 [assembly: AssemblyBuildDate("$WCNOW$")]
  • trunk/sources/HeuristicLab.GP.Operators/3.3/HeuristicLab.GP.Operators-3.3.csproj

    r2682 r2750  
    8080  </ItemGroup>
    8181  <ItemGroup>
     82    <None Include="HeuristicLabGPOperatorsPlugin.cs.frame" />
    8283    <Compile Include="Logging\SymbolFrequencyAnalyser.cs" />
    8384    <Compile Include="Util.cs" />
     
    161162set Outdir=$(Outdir)
    162163
    163 call PreBuildEvent.cmd</PreBuildEvent>
     164call PreBuildEvent.cmd
     165SubWCRev "%25ProjectDir%25/" "%25ProjectDir%25/HeuristicLabGPOperatorsPlugin.cs.frame" "%25ProjectDir%25/HeuristicLabGPOperatorsPlugin.cs"</PreBuildEvent>
    164166  </PropertyGroup>
    165167</Project>
  • trunk/sources/HeuristicLab.GP.Operators/3.3/HeuristicLabGPOperatorsPlugin.cs

    r2591 r2750  
    2626
    2727namespace HeuristicLab.GP.Operators {
    28   [Plugin("HeuristicLab.GP.Operators-3.3")]
     28  [Plugin("HeuristicLab.GP.Operators", "3.3.0.2730")]
    2929  [PluginFile("HeuristicLab.GP.Operators-3.3.dll", PluginFileType.Assembly)]
    3030  [PluginDependency("HeuristicLab.Core-3.2")]
    3131  [PluginDependency("HeuristicLab.Data-3.2")]
    3232  [PluginDependency("HeuristicLab.Evolutionary-3.2")]
    33   [PluginDependency("HeuristicLab.GP-3.3")]
    34   [PluginDependency("HeuristicLab.GP.Interfaces-3.3")]
     33  [PluginDependency("HeuristicLab.GP", "3.3")]
     34  [PluginDependency("HeuristicLab.GP.Interfaces", "3.3")]
    3535  [PluginDependency("HeuristicLab.Operators-3.2")]
    3636  [PluginDependency("HeuristicLab.Random-3.2")]
  • trunk/sources/HeuristicLab.GP.Operators/3.3/Properties/AssemblyInfo.frame

    r2222 r2750  
    2323using System.Runtime.CompilerServices;
    2424using System.Runtime.InteropServices;
    25 using HeuristicLab.PluginInfrastructure;
    2625
    2726// General Information about an assembly is controlled through the following
     
    3332[assembly: AssemblyCompany("")]
    3433[assembly: AssemblyProduct("HeuristicLab")]
    35 [assembly: AssemblyCopyright("(c) 2002-2008 HEAL")]
     34[assembly: AssemblyCopyright("(c) 2002-2010 HEAL")]
    3635[assembly: AssemblyTrademark("")]
    3736[assembly: AssemblyCulture("")]
     
    5453// You can specify all the values or you can default the Revision and Build Numbers
    5554// by using the '*' as shown below:
    56 [assembly: AssemblyVersion("3.3.0.$WCREV$")]
     55[assembly: AssemblyVersion("3.3.0.0")]
    5756[assembly: AssemblyFileVersion("3.3.0.$WCREV$")]
    58 [assembly: AssemblyBuildDate("$WCNOW$")]
  • trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/HeuristicLab.GP.StructureIdentification-3.3.csproj

    r2722 r2750  
    8585    <Compile Include="BaseClasses\FunctionTreeBase.cs" />
    8686    <Compile Include="BaseClasses\TreeEvaluatorBase.cs" />
     87    <None Include="HeuristicLabGPStructureIdentificationPlugin.cs.frame" />
    8788    <Compile Include="LinearScalingPredictorBuilder.cs" />
    8889    <Compile Include="Evaluators\VariableFrequencyBasedImpactCalculator.cs" />
     
    253254set Outdir=$(Outdir)
    254255
    255 call PreBuildEvent.cmd</PreBuildEvent>
     256call PreBuildEvent.cmd
     257SubWCRev "%25ProjectDir%25/" "%25ProjectDir%25/HeuristicLabGPStructureIdentificationPlugin.cs.frame" "%25ProjectDir%25/HeuristicLabGPStructureIdentificationPlugin.cs"</PreBuildEvent>
    256258  </PropertyGroup>
    257259</Project>
  • trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/HeuristicLabGPStructureIdentificationPlugin.cs

    r2591 r2750  
    2323
    2424namespace HeuristicLab.GP.StructureIdentification {
    25   [Plugin("HeuristicLab.GP.StructureIdentification-3.3")]
     25  [Plugin("HeuristicLab.GP.StructureIdentification", "3.3.0.2728")]
    2626  [PluginFile("HeuristicLab.GP.StructureIdentification-3.3.dll", PluginFileType.Assembly)]
    2727  [PluginDependency("HeuristicLab.Common-3.2")]
     
    3030  [PluginDependency("HeuristicLab.DataAnalysis-3.2")]
    3131  [PluginDependency("HeuristicLab.Evolutionary-3.2")]
    32   [PluginDependency("HeuristicLab.GP-3.3")]
    33   [PluginDependency("HeuristicLab.GP.Interfaces-3.3")]
    34   [PluginDependency("HeuristicLab.GP.Operators-3.3")]
     32  [PluginDependency("HeuristicLab.GP", "3.3")]
     33  [PluginDependency("HeuristicLab.GP.Interfaces", "3.3")]
     34  [PluginDependency("HeuristicLab.GP.Operators", "3.3")]
    3535  [PluginDependency("HeuristicLab.Logging-3.2")]
    3636  [PluginDependency("HeuristicLab.Modeling-3.2")]
  • trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/Properties/AssemblyInfo.frame

    r1527 r2750  
    2323using System.Runtime.CompilerServices;
    2424using System.Runtime.InteropServices;
    25 using HeuristicLab.PluginInfrastructure;
    2625
    2726// General Information about an assembly is controlled through the following
     
    3332[assembly: AssemblyCompany("")]
    3433[assembly: AssemblyProduct("HeuristicLab")]
    35 [assembly: AssemblyCopyright("(c) 2002-2008 HEAL")]
     34[assembly: AssemblyCopyright("(c) 2002-2010 HEAL")]
    3635[assembly: AssemblyTrademark("")]
    3736[assembly: AssemblyCulture("")]
     
    5453// You can specify all the values or you can default the Revision and Build Numbers
    5554// by using the '*' as shown below:
    56 [assembly: AssemblyVersion("3.3.0.$WCREV$")]
     55[assembly: AssemblyVersion("3.3.0.0")]
    5756[assembly: AssemblyFileVersion("3.3.0.$WCREV$")]
    58 [assembly: AssemblyBuildDate("$WCNOW$")]
  • trunk/sources/HeuristicLab.GP/3.3/HeuristicLab.GP-3.3.csproj

    r2728 r2750  
    8989    <Compile Include="BaseClasses\Terminal.cs" />
    9090    <Compile Include="BaseClasses\UnaryFunction.cs" />
     91    <None Include="HeuristicLabGPPlugin.cs.frame" />
    9192    <Compile Include="FunctionLibraryInjectorView.cs">
    9293      <SubType>UserControl</SubType>
     
    178179set Outdir=$(Outdir)
    179180
    180 call PreBuildEvent.cmd</PreBuildEvent>
     181call PreBuildEvent.cmd
     182SubWCRev "%25ProjectDir%25/" "%25ProjectDir%25/HeuristicLabGPPlugin.cs.frame" "%25ProjectDir%25/HeuristicLabGPPlugin.cs"</PreBuildEvent>
    181183  </PropertyGroup>
    182184</Project>
  • trunk/sources/HeuristicLab.GP/3.3/HeuristicLabGPPlugin.cs

    r2591 r2750  
    2626
    2727namespace HeuristicLab.GP {
    28   [Plugin("HeuristicLab.GP-3.3")]
     28  [Plugin("HeuristicLab.GP", "3.3.0.2730")]
    2929  [PluginFile("HeuristicLab.GP-3.3.dll", PluginFileType.Assembly)]
    30   [PluginDependency("HeuristicLab.GP.Interfaces-3.3")]
     30  [PluginDependency("HeuristicLab.GP.Interfaces", "3.3")]
    3131  [PluginDependency("HeuristicLab.Random-3.2")]
    3232  public class HeuristicLabGPPlugin : PluginBase {
  • trunk/sources/HeuristicLab.GP/3.3/Properties/AssemblyInfo.frame

    r1527 r2750  
    2323using System.Runtime.CompilerServices;
    2424using System.Runtime.InteropServices;
    25 using HeuristicLab.PluginInfrastructure;
    2625
    2726// General Information about an assembly is controlled through the following
     
    3332[assembly: AssemblyCompany("")]
    3433[assembly: AssemblyProduct("HeuristicLab")]
    35 [assembly: AssemblyCopyright("(c) 2002-2008 HEAL")]
     34[assembly: AssemblyCopyright("(c) 2002-2010 HEAL")]
    3635[assembly: AssemblyTrademark("")]
    3736[assembly: AssemblyCulture("")]
     
    5453// You can specify all the values or you can default the Revision and Build Numbers
    5554// by using the '*' as shown below:
    56 [assembly: AssemblyVersion("3.3.0.$WCREV$")]
     55[assembly: AssemblyVersion("3.3.0.0")]
    5756[assembly: AssemblyFileVersion("3.3.0.$WCREV$")]
    58 [assembly: AssemblyBuildDate("$WCNOW$")]
  • trunk/sources/HeuristicLab.PluginInfrastructure/Attributes/AssemblyBuildDateAttribute.cs

    r2504 r2750  
    4545    /// <exception cref="FormatException">Thrown when the time stamp could not be parsed as build date.</exception>
    4646    /// <param name="buildDate">The build date of the assembly.</param>
     47    [Obsolete]
    4748    public AssemblyBuildDateAttribute(string buildDate)
    4849      : base() {
  • trunk/sources/HeuristicLab.PluginInfrastructure/Attributes/PluginAttribute.cs

    r2748 r2750  
    4747    }
    4848
     49    private Version version;
     50    /// <summary>
     51    /// Gets the version of the plugin.
     52    /// </summary>
     53    public Version Version {
     54      get { return version; }
     55    }
     56
     57    [Obsolete]
     58    public PluginAttribute(string name) : this(name, "0.0.0.0") { }
     59
    4960    /// <summary>
    5061    /// Initializes a new instance of <see cref="PluginAttribute"/>.
    5162    /// <param name="name">Name of the plugin</param>
     63    /// <param name="version">Version of the plugin</param>
    5264    /// </summary>
    53     public PluginAttribute(string name)
    54       : this(name, string.Empty) {
     65    public PluginAttribute(string name, string version)
     66      : this(name, string.Empty, version) {
    5567    }
    5668
    5769    /// <summary>
    5870    /// Initializes a new instance of <see cref="PluginAttribute"/>.
     71    /// </summary>
    5972    /// <param name="name">Name of the plugin</param>
    6073    /// <param name="description">Description of the plugin</param>
    61     /// </summary>
    62     public PluginAttribute(string name, string description) {
     74    /// <param name="version">Version of the plugin</param>
     75    public PluginAttribute(string name, string description, string version) {
    6376      if (string.IsNullOrEmpty(name)) throw new ArgumentException("Plugin name is null or empty.");
    6477      if (description == null) throw new ArgumentNullException("description");
     78      if (string.IsNullOrEmpty(version)) new ArgumentException("Version string is null or empty.");
    6579      this.name = name;
    6680      this.description = description;
     81      this.version = new Version(version); // throws format exception if the version string can't be parsed
    6782    }
    6883  }
  • trunk/sources/HeuristicLab.PluginInfrastructure/Attributes/PluginDependencyAttribute.cs

    r2748 r2750  
    3939    }
    4040
     41    private Version version;
     42    /// <summary>
     43    /// Gets the version of the plugin dependency.
     44    /// </summary>
     45    public Version Version {
     46      get { return version; }
     47    }
     48
    4149    /// <summary>
    4250    /// Initializes a new instance of <see cref="PluginDependencyAttribute"/>.
    4351    /// <param name="dependency">The name of the plugin that is needed to load a plugin.</param>
    4452    /// </summary>
    45     public PluginDependencyAttribute(string dependency) {
    46       if (string.IsNullOrEmpty(dependency)) throw new ArgumentException("Dependency is null or empty.", "dependency");
     53    [Obsolete]
     54    public PluginDependencyAttribute(string dependency)
     55      : this(dependency, "0.0.0.0") {
     56    }
     57
     58    public PluginDependencyAttribute(string dependency, string version) {
     59      if (string.IsNullOrEmpty(dependency)) throw new ArgumentException("Dependency name is null or empty.", "dependency");
     60      if (string.IsNullOrEmpty(version)) throw new ArgumentException("Dependency version is null or empty.", "version");
    4761      this.dependency = dependency;
     62      this.version = new Version(version); // throws format exception if the version string can't be parsed
    4863    }
    4964  }
  • trunk/sources/HeuristicLab.PluginInfrastructure/InvalidPluginException.cs

    r2504 r2750  
    3131  [Serializable]
    3232  public sealed class InvalidPluginException : Exception {
     33    /// <summary>
     34    /// Initializes a new InvalidPluginException
     35    /// </summary>
    3336    public InvalidPluginException() : base() { }
     37    /// <summary>
     38    /// Initializes a new InvalidPluginException with an error message.
     39    /// </summary>
     40    /// <param name="message">The exception message</param>
    3441    public InvalidPluginException(string message) : base(message) { }
    35     public InvalidPluginException(string message, Exception exception) : base(message, exception) { }
     42    /// <summary>
     43    /// Initializes a new InvalidPluginException with an error message and an inner exception.
     44    /// </summary>
     45    /// <param name="message">The exception message.</param>
     46    /// <param name="innerException">The original exception.</param>
     47    public InvalidPluginException(string message, Exception innerException) : base(message, innerException) { }
     48    /// <summary>
     49    /// Constructor for serialization.
     50    /// </summary>
     51    /// <param name="info">The serialization info.</param>
     52    /// <param name="contex">The serialization context.</param>
    3653    private InvalidPluginException(SerializationInfo info, StreamingContext contex) : base(info, contex) { }
    3754  }
  • trunk/sources/HeuristicLab.PluginInfrastructure/Manager/PluginValidator.cs

    r2690 r2750  
    3636  /// </summary>
    3737  internal sealed class PluginValidator : MarshalByRefObject {
     38    // private class to store plugin dependency declarations while reflecting over plugins
     39    private class PluginDependency {
     40      public string Name { get; private set; }
     41      public Version Version { get; private set; }
     42
     43      public PluginDependency(string name, Version version) {
     44        this.Name = name;
     45        this.Version = version;
     46      }
     47    }
     48
     49
    3850    internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded;
    3951
    40     private Dictionary<PluginDescription, List<string>> pluginDependencies;
     52    private Dictionary<PluginDescription, IEnumerable<PluginDependency>> pluginDependencies;
    4153
    4254    private List<ApplicationDescription> applications;
     
    6173
    6274    internal PluginValidator() {
    63       this.pluginDependencies = new Dictionary<PluginDescription, List<string>>();
     75      this.pluginDependencies = new Dictionary<PluginDescription, IEnumerable<PluginDependency>>();
    6476
    6577      // ReflectionOnlyAssemblyResolveEvent must be handled because we load assemblies from the plugin path
     
    250262      // get all attributes of that type
    251263      IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(pluginType);
    252       List<string> pluginDependencies = new List<string>();
     264      List<PluginDependency> pluginDependencies = new List<PluginDependency>();
    253265      List<PluginFile> pluginFiles = new List<PluginFile>();
    254266      string pluginName = null;
    255267      string pluginDescription = null;
     268      string pluginVersion = "0.0.0.0";
    256269      // iterate through all custom attributes and search for attributed that we are interested in
    257270      foreach (CustomAttributeData attributeData in attributes) {
    258271        if (IsAttributeDataForType(attributeData, typeof(PluginAttribute))) {
    259272          pluginName = (string)attributeData.ConstructorArguments[0].Value;
    260           if (attributeData.ConstructorArguments.Count() == 2) {
    261             pluginDescription = (string)attributeData.ConstructorArguments[1].Value;
    262           } else pluginDescription = pluginName;
     273          if (attributeData.ConstructorArguments.Count() > 1) {
     274            pluginVersion = (string)attributeData.ConstructorArguments[1].Value;
     275          }
     276          if (attributeData.ConstructorArguments.Count() > 2) {
     277            pluginDescription = (string)attributeData.ConstructorArguments[2].Value;
     278          } else {
     279            // no description given => use name as description
     280            pluginDescription = pluginName;
     281          }
    263282        } else if (IsAttributeDataForType(attributeData, typeof(PluginDependencyAttribute))) {
    264           pluginDependencies.Add((string)attributeData.ConstructorArguments[0].Value);
     283          string name = (string)attributeData.ConstructorArguments[0].Value;
     284          Version version = new Version();
     285          // check if version is given for now
     286          // later when the constructore of PluginDependencyAttribute with only one argument has been removed
     287          // this conditional can be removed as well
     288          if (attributeData.ConstructorArguments.Count > 1) {
     289            try {
     290              version = new Version((string)attributeData.ConstructorArguments[1].Value); // throws FormatException
     291            }
     292            catch (FormatException ex) {
     293              throw new InvalidPluginException("Invalid version format of dependency " + name + " in plugin " + pluginType.ToString(), ex);
     294            }
     295          }
     296          pluginDependencies.Add(new PluginDependency(name, version));
    265297        } else if (IsAttributeDataForType(attributeData, typeof(PluginFileAttribute))) {
    266298          string pluginFileName = (string)attributeData.ConstructorArguments[0].Value;
     
    270302      }
    271303
    272       var buildDates = from attr in CustomAttributeData.GetCustomAttributes(pluginType.Assembly)
    273                        where IsAttributeDataForType(attr, typeof(AssemblyBuildDateAttribute))
    274                        select (string)attr.ConstructorArguments[0].Value;
    275 
    276304      // minimal sanity check of the attribute values
    277305      if (!string.IsNullOrEmpty(pluginName) &&
    278306          pluginFiles.Count > 0 &&                                   // at least on file
    279           pluginFiles.Any(f => f.Type == PluginFileType.Assembly) && // at least on assembly
    280           buildDates.Count() == 1) {                                 // build date must be declared
     307          pluginFiles.Any(f => f.Type == PluginFileType.Assembly)) { // at least on assembly
    281308        // create a temporary PluginDescription that contains the attribute values
    282309        PluginDescription info = new PluginDescription();
    283310        info.Name = pluginName;
    284311        info.Description = pluginDescription;
    285         info.Version = pluginType.Assembly.GetName().Version;
    286         info.BuildDate = DateTime.Parse(buildDates.Single(), System.Globalization.CultureInfo.InvariantCulture);
     312        info.Version = new Version(pluginVersion);
    287313        info.AddFiles(pluginFiles);
    288314
     
    303329    private void BuildDependencyTree(IEnumerable<PluginDescription> pluginDescriptions) {
    304330      foreach (var desc in pluginDescriptions) {
    305         foreach (string pluginName in pluginDependencies[desc]) {
    306           var matchingDescriptions = pluginDescriptions.Where(x => x.Name == pluginName);
     331        foreach (var dependency in pluginDependencies[desc]) {
     332          var matchingDescriptions = from availablePlugin in pluginDescriptions
     333                                     where availablePlugin.Name == dependency.Name
     334                                     where IsCompatiblePluginVersion(availablePlugin.Version, dependency.Version)
     335                                     select availablePlugin;
    307336          if (matchingDescriptions.Count() > 0) {
    308337            desc.AddDependency(matchingDescriptions.Single());
     
    313342        }
    314343      }
     344    }
     345
     346    /// <summary>
     347    /// Checks if version <paramref name="available"/> is compatible to version <paramref name="requested"/>.
     348    /// Note: the compatibility relation is not bijective.
     349    /// Compatibility rules:
     350    ///  * major and minor number must be the same
     351    ///  * build and revision number of <paramref name="available"/> must be larger or equal to <paramref name="requested"/>.
     352    /// </summary>
     353    /// <param name="available">The available version which should be compared to <paramref name="requested"/>.</param>
     354    /// <param name="requested">The requested version that must be matched.</param>
     355    /// <returns></returns>
     356    private bool IsCompatiblePluginVersion(Version available, Version requested) {
     357      // this condition must be removed after all plugins have been updated to declare plugin and dependency versions
     358      if (
     359        (requested.Major == 0 && requested.Minor == 0) ||
     360        (available.Major == 0 && available.Minor == 0)) return true;
     361      return
     362        available.Major == requested.Major &&
     363        available.Minor == requested.Minor &&
     364        available.Build >= requested.Build &&
     365        available.Revision >= requested.Revision;
    315366    }
    316367
Note: See TracChangeset for help on using the changeset viewer.