diff --git a/src/PlugIns/PlugInManager.cs b/src/PlugIns/PlugInManager.cs index ef87e5b5f..91008fddd 100644 --- a/src/PlugIns/PlugInManager.cs +++ b/src/PlugIns/PlugInManager.cs @@ -90,6 +90,7 @@ public PlugInManager(ICollection? configurations, ILoggerFa public void DiscoverAndRegisterPlugIns() { var plugIns = this.DiscoverNewPlugIns(); + this.ValidateNoDuplicateGuids(plugIns); this.RegisterPlugIns(plugIns); } @@ -100,6 +101,7 @@ public void DiscoverAndRegisterPlugIns() public void DiscoverAndRegisterPlugIns(Assembly assembly) { var plugIns = this.DiscoverNewPlugIns(this.DiscoverPlugIns(assembly)); + this.ValidateNoDuplicateGuids(plugIns); this.RegisterPlugIns(plugIns); } @@ -304,7 +306,7 @@ public void RegisterPlugIn() } else { - this._logger.LogWarning($"Plugin {typeof(TPlugInClass)} wasn't registered, because it's not an implementation of an interface which is marked with {nameof(PlugInPointAttribute)} or {nameof(CustomPlugInContainerAttribute)}."); + this._logger.LogWarning("Plugin {PlugInClass} wasn't registered, because it's not an implementation of an interface which is marked with PlugInPointAttribute or CustomPlugInContainerAttribute.", typeof(TPlugInClass)); } } @@ -353,6 +355,20 @@ public void ConfigurePlugIn(Guid plugInId, PlugInConfiguration configuration) } } + private void ValidateNoDuplicateGuids(IEnumerable plugIns) + { + var allPlugIns = plugIns.Concat(this._knownPlugIns.Values).Distinct(); + var duplicates = allPlugIns.GroupBy(t => t.GUID).Where(g => g.Count() > 1).ToList(); + if (duplicates.Count == 0) + { + return; + } + + var message = string.Join("; ", duplicates.Select(g => + $"{g.Key} used by {string.Join(", ", g.Select(t => t.FullName ?? t.Name))}")); + throw new DuplicatePlugInGuidException(message); + } + private Type? GetCustomPlugInPointType(Type interfaceType) { if (interfaceType.GetCustomAttribute() != null) @@ -415,13 +431,13 @@ private void ReadConfiguration(PlugInConfiguration configuration, HashSet plugIns) } catch (Exception e) { - this._logger.LogError(e, $"Couldn't register plugin type {plugIn}"); + this._logger.LogError(e, "Couldn't register plugin type {PlugIn}", plugIn); this._logger.LogError("TODO: Use ServiceContainer"); } @@ -543,6 +559,21 @@ private void RegisterPlugIns(IEnumerable plugIns) } } + /// + /// Exception that is thrown when two different plugin types share the same . + /// + public class DuplicatePlugInGuidException : InvalidOperationException + { + /// + /// Initializes a new instance of the class. + /// + /// The message. + public DuplicatePlugInGuidException(string message) + : base(message) + { + } + } + /// /// Exception that occurs when the created proxy doesn't implement the expected interface . ///