From b5c07d9eff66d9c021a34c689e7f3d4692bdad9a Mon Sep 17 00:00:00 2001 From: ChDF T Date: Fri, 1 Sep 2017 17:31:42 +0200 Subject: [PATCH] add a lot of documentation --- ExtensionBridge.Sample.Host/Program.cs | 2 +- ...bySource.cs => DirectoryAssemblySource.cs} | 19 ++++++++++++--- ExtensionBridge/Extension.cs | 19 +++++++++++++++ ExtensionBridge/ExtensionAttribute.cs | 5 +++- ExtensionBridge/ExtensionBridge.csproj | 2 +- ExtensionBridge/ExtensionContractAttribute.cs | 5 +++- ExtensionBridge/FileLoadResult.cs | 24 +++++++++++++++++++ ExtensionBridge/IAssemblySource.cs | 6 +++++ ExtensionBridge/KnownAssemblySource.cs | 10 ++++++++ ExtensionBridge/LocalAssemblySource.cs | 6 ++++- ExtensionBridge/Repository.cs | 15 +++++++++++- 11 files changed, 104 insertions(+), 9 deletions(-) rename ExtensionBridge/{DirectoryAssemlbySource.cs => DirectoryAssemblySource.cs} (86%) diff --git a/ExtensionBridge.Sample.Host/Program.cs b/ExtensionBridge.Sample.Host/Program.cs index 7f2bb73..1253d2b 100644 --- a/ExtensionBridge.Sample.Host/Program.cs +++ b/ExtensionBridge.Sample.Host/Program.cs @@ -13,7 +13,7 @@ static void Main(string[] args) Repository repository = new Repository(); //relative path are relative to the application directory, not the current directory - DirectoryAssemlbySource directorySource = new DirectoryAssemlbySource("Extensions", "*.mycustomextensionformat"); + DirectoryAssemblySource directorySource = new DirectoryAssemblySource("Extensions", "*.mycustomextensionformat"); //you have to call directorySource.LoadAssemblies() *before* you add directorySource to the repository (this actually loads the assemblies from the found files) //while it is recommended to check the returned collection of FileLoadResults for any unsuccessful items (and show that information to the user/log it somewhere), you can safely ignore the return value of directorySource.LoadAssemblies() //note that the call succeeds, even when the specified directory (in this case Extensions) can not be found diff --git a/ExtensionBridge/DirectoryAssemlbySource.cs b/ExtensionBridge/DirectoryAssemblySource.cs similarity index 86% rename from ExtensionBridge/DirectoryAssemlbySource.cs rename to ExtensionBridge/DirectoryAssemblySource.cs index b049152..25254ea 100644 --- a/ExtensionBridge/DirectoryAssemlbySource.cs +++ b/ExtensionBridge/DirectoryAssemblySource.cs @@ -11,9 +11,16 @@ namespace ExtensionBridge /// /// Uses all assemblies found in a directory as a source for extensions. /// - public class DirectoryAssemlbySource : IAssemblySource + public class DirectoryAssemblySource : IAssemblySource { + /// + /// Search pattern matching only DLLs with .dll extension + /// public const string DllSearchPattern = "*.dll"; + + /// + /// Search pattern matching all files + /// public const string AllFilesSearchPattern = "*"; /// relative or absolute path to a directory, see for detailed information @@ -24,7 +31,7 @@ public class DirectoryAssemlbySource : IAssemblySource /// /// /// - public DirectoryAssemlbySource(string directory, string searchPattern = DllSearchPattern) + public DirectoryAssemblySource(string directory, string searchPattern = DllSearchPattern) { Directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, directory); SearchPattern = searchPattern; @@ -47,12 +54,18 @@ public DirectoryAssemlbySource(string directory, string searchPattern = DllSearc /// public string SearchPattern { get; private set; } + /// + /// Currently known set of assemblies. + /// + /// + /// This value is updated when is called. + /// protected IEnumerable Assemblies { get; private set; } /// /// Loads all assemblies matching from the specified Directory /// - /// Collection of containing information about the status of each found file (most notably whether it could be loaded successfully) + /// Collection of containing information about the status of each found file (most notably whether it could be loaded successfully) /// /// public IEnumerable LoadAssemblies() diff --git a/ExtensionBridge/Extension.cs b/ExtensionBridge/Extension.cs index b216569..6047925 100644 --- a/ExtensionBridge/Extension.cs +++ b/ExtensionBridge/Extension.cs @@ -8,8 +8,17 @@ namespace ExtensionBridge { + /// + /// Represents an extension implementing . + /// + /// Contract interface public class Extension where TContract : class { + /// + /// Create a new Extension instance based on the represented extension type and providing source. + /// + /// Type of the extension. + /// that provided the assembly containing this extension. public Extension(Type extensionType, IAssemblySource source) { if (!typeof(TContract).IsAssignableFrom(extensionType)) @@ -25,8 +34,18 @@ public Extension(Type extensionType, IAssemblySource source) Source = source; } + /// + /// Gets the Type of the represented extension. + /// + /// + /// This attribute is intended for advanced use-cases, like extensions with non-default constructors. + /// Use to create a new instance of the represented extension using the default constructor. + /// public Type ExtensionType { get; private set; } + /// + /// Gets the that provided this extension. + /// public IAssemblySource Source { get; private set; } /// diff --git a/ExtensionBridge/ExtensionAttribute.cs b/ExtensionBridge/ExtensionAttribute.cs index 5af23f5..282531d 100644 --- a/ExtensionBridge/ExtensionAttribute.cs +++ b/ExtensionBridge/ExtensionAttribute.cs @@ -12,9 +12,12 @@ namespace ExtensionBridge [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] public sealed class ExtensionAttribute : Attribute { + /// + /// Create a new ExtensionAttribute based on a declared contract interface. + /// + /// contract interface type / null to implicitly declare all implemented contracts public ExtensionAttribute(Type contract) { - if (contract == null) { throw new ArgumentNullException("contract"); } Contract = contract; } diff --git a/ExtensionBridge/ExtensionBridge.csproj b/ExtensionBridge/ExtensionBridge.csproj index 6f8531e..95684f4 100644 --- a/ExtensionBridge/ExtensionBridge.csproj +++ b/ExtensionBridge/ExtensionBridge.csproj @@ -48,7 +48,7 @@ - + diff --git a/ExtensionBridge/ExtensionContractAttribute.cs b/ExtensionBridge/ExtensionContractAttribute.cs index e7bcfcf..b9cff2d 100644 --- a/ExtensionBridge/ExtensionContractAttribute.cs +++ b/ExtensionBridge/ExtensionContractAttribute.cs @@ -7,11 +7,14 @@ namespace ExtensionBridge { /// - /// marks the decorated interface as base for an extension + /// Declares the decorated interface as base for an extension /// [AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] public sealed class ExtensionContractAttribute : Attribute { + /// + /// Create a new ExtensionContractAttribute instance. + /// public ExtensionContractAttribute() { } } } diff --git a/ExtensionBridge/FileLoadResult.cs b/ExtensionBridge/FileLoadResult.cs index 37f648d..fea94ae 100644 --- a/ExtensionBridge/FileLoadResult.cs +++ b/ExtensionBridge/FileLoadResult.cs @@ -6,16 +6,31 @@ namespace ExtensionBridge { + /// + /// Wraps the result of an attempt to load a file as assembly. + /// public class FileLoadResult { + /// + /// Create a new instance for a loaded file. + /// + /// Path to the file/assembly. + /// exception thrown while loading the assembly / null if no exception occurred public FileLoadResult(string path, Exception e) { Exception = e; FilePath = path; } + /// + /// Create a new instance for a successfully loaded file. + /// + /// Path to the file/assembly. public FileLoadResult(string path) : this(path, null) { } + /// + /// True if the file was loaded successfully, false otherwise. + /// public bool IsSuccess { get @@ -24,8 +39,17 @@ public bool IsSuccess } } + /// + /// Path to the file. + /// + /// + /// This path may be local or remote and may not even exist. + /// public string FilePath { get; private set; } + /// + /// Gets the exception that was thrown while loading the file as assembly. Null iif no exception was thrown. + /// public Exception Exception { get; private set; } } } diff --git a/ExtensionBridge/IAssemblySource.cs b/ExtensionBridge/IAssemblySource.cs index 40b505d..80cb7d9 100644 --- a/ExtensionBridge/IAssemblySource.cs +++ b/ExtensionBridge/IAssemblySource.cs @@ -7,6 +7,12 @@ namespace ExtensionBridge { + /// + /// Provides assemblies for extension-lookup. + /// + /// + /// + /// public interface IAssemblySource { /// diff --git a/ExtensionBridge/KnownAssemblySource.cs b/ExtensionBridge/KnownAssemblySource.cs index cb087c5..2113bd2 100644 --- a/ExtensionBridge/KnownAssemblySource.cs +++ b/ExtensionBridge/KnownAssemblySource.cs @@ -12,13 +12,23 @@ namespace ExtensionBridge /// public class KnownAssemblySource : IAssemblySource { + /// + /// Create a new KnownAssemblySource instance using a known assembly. + /// + /// Assembly which will be provided as source for extension-lookups public KnownAssemblySource(Assembly assembly) { + if (assembly.ReflectionOnly) { throw new ArgumentException("assembly is loaded into reflection-only context and not execution-context."); } + Assembly = assembly; } + /// + /// Assembly provided as source + /// public Assembly Assembly { get; private set; } + /// public IEnumerable GetAssemblies() { return new Assembly[] { Assembly }; diff --git a/ExtensionBridge/LocalAssemblySource.cs b/ExtensionBridge/LocalAssemblySource.cs index 32d0df2..63c6258 100644 --- a/ExtensionBridge/LocalAssemblySource.cs +++ b/ExtensionBridge/LocalAssemblySource.cs @@ -8,12 +8,16 @@ namespace ExtensionBridge { /// - /// Uses the currently executing assembly as source for extensions. + /// Uses the entry assembly as source for extensions. /// public class LocalAssemblySource : IAssemblySource { + /// + /// Create a new LocalAssemblySource instance. + /// public LocalAssemblySource() { } + /// public IEnumerable GetAssemblies() { return new Assembly[] { Assembly.GetEntryAssembly() }; diff --git a/ExtensionBridge/Repository.cs b/ExtensionBridge/Repository.cs index baba81a..7736d1b 100644 --- a/ExtensionBridge/Repository.cs +++ b/ExtensionBridge/Repository.cs @@ -7,13 +7,26 @@ namespace ExtensionBridge { + /// + /// Provides extensions based on implemented contracts. + /// public class Repository { + /// + /// Create a new Repository instance with an empty collection. + /// public Repository() { _Sources = new LinkedList(); } + /// + /// Create a new Repository instance with a given collection. + /// + /// sources + /// + /// The contents of the parameter are copied into a new collection. + /// public Repository(IEnumerable sources) { _Sources = new LinkedList(sources); @@ -61,7 +74,7 @@ public IEnumerable> GetExtensions() where TContr { foreach (var assembly in assemblies) { - foreach (Type type in assembly.GetTypes()) + foreach (Type type in assembly.GetExportedTypes()) { //check first, if the contract is implemented at all; otherwise the search for an extension-attribute isn't necessary //check ContainsGenericParameters, because generic types with unspecified type parameters cannot be instantiated...