Skip to content

Commit

Permalink
add a lot of documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
chdft committed Sep 1, 2017
1 parent 846e995 commit b5c07d9
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 9 deletions.
2 changes: 1 addition & 1 deletion ExtensionBridge.Sample.Host/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ namespace ExtensionBridge
/// <summary>
/// Uses all assemblies found in a directory as a source for extensions.
/// </summary>
public class DirectoryAssemlbySource : IAssemblySource
public class DirectoryAssemblySource : IAssemblySource
{
/// <summary>
/// Search pattern matching only DLLs with .dll extension
/// </summary>
public const string DllSearchPattern = "*.dll";

/// <summary>
/// Search pattern matching all files
/// </summary>
public const string AllFilesSearchPattern = "*";

/// <param name="directory">relative or absolute path to a directory, see <see cref="Directory"/> for detailed information</param>
Expand All @@ -24,7 +31,7 @@ public class DirectoryAssemlbySource : IAssemblySource
/// </note>
/// </remarks>
/// <seealso cref="DllSearchPattern"/>
public DirectoryAssemlbySource(string directory, string searchPattern = DllSearchPattern)
public DirectoryAssemblySource(string directory, string searchPattern = DllSearchPattern)
{
Directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, directory);
SearchPattern = searchPattern;
Expand All @@ -47,12 +54,18 @@ public DirectoryAssemlbySource(string directory, string searchPattern = DllSearc
/// </remarks>
public string SearchPattern { get; private set; }

/// <summary>
/// Currently known set of assemblies.
/// </summary>
/// <remarks>
/// This value is updated when <see cref="LoadAssemblies"/> is called.
/// </remarks>
protected IEnumerable<Assembly> Assemblies { get; private set; }

/// <summary>
/// Loads all assemblies matching from the specified Directory
/// </summary>
/// <returns>Collection of <see cref="FileLoadResults"/> containing information about the status of each found file (most notably whether it could be loaded successfully)</returns>
/// <returns>Collection of <see cref="FileLoadResult"/> containing information about the status of each found file (most notably whether it could be loaded successfully)</returns>
/// <seealso cref="Directory"/>
/// <seealso cref="SearchPattern"/>
public IEnumerable<FileLoadResult> LoadAssemblies()
Expand Down
19 changes: 19 additions & 0 deletions ExtensionBridge/Extension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@

namespace ExtensionBridge
{
/// <summary>
/// Represents an extension implementing <typeparamref name="TContract"/>.
/// </summary>
/// <typeparam name="TContract">Contract interface</typeparam>
public class Extension<TContract> where TContract : class
{
/// <summary>
/// Create a new Extension instance based on the represented extension type and providing source.
/// </summary>
/// <param name="extensionType">Type of the extension.</param>
/// <param name="source"><see cref="IAssemblySource"/> that provided the assembly containing this extension.</param>
public Extension(Type extensionType, IAssemblySource source)
{
if (!typeof(TContract).IsAssignableFrom(extensionType))
Expand All @@ -25,8 +34,18 @@ public Extension(Type extensionType, IAssemblySource source)
Source = source;
}

/// <summary>
/// Gets the Type of the represented extension.
/// </summary>
/// <remarks>
/// This attribute is intended for advanced use-cases, like extensions with non-default constructors.
/// Use <see cref="CreateInstance"/> to create a new instance of the represented extension using the default constructor.
/// </remarks>
public Type ExtensionType { get; private set; }

/// <summary>
/// Gets the <see cref="IAssemblySource"/> that provided this extension.
/// </summary>
public IAssemblySource Source { get; private set; }

/// <summary>
Expand Down
5 changes: 4 additions & 1 deletion ExtensionBridge/ExtensionAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ namespace ExtensionBridge
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
public sealed class ExtensionAttribute : Attribute
{
/// <summary>
/// Create a new ExtensionAttribute based on a declared contract interface.
/// </summary>
/// <param name="contract">contract interface type / null to implicitly declare all implemented contracts</param>
public ExtensionAttribute(Type contract)
{
if (contract == null) { throw new ArgumentNullException("contract"); }
Contract = contract;
}

Expand Down
2 changes: 1 addition & 1 deletion ExtensionBridge/ExtensionBridge.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DirectoryAssemlbySource.cs" />
<Compile Include="DirectoryAssemblySource.cs" />
<Compile Include="Extension.cs" />
<Compile Include="ExtensionAttribute.cs" />
<Compile Include="ExtensionContractAttribute.cs" />
Expand Down
5 changes: 4 additions & 1 deletion ExtensionBridge/ExtensionContractAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
namespace ExtensionBridge
{
/// <summary>
/// marks the decorated interface as base for an extension
/// Declares the decorated interface as base for an extension
/// </summary>
[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
public sealed class ExtensionContractAttribute : Attribute
{
/// <summary>
/// Create a new ExtensionContractAttribute instance.
/// </summary>
public ExtensionContractAttribute() { }
}
}
24 changes: 24 additions & 0 deletions ExtensionBridge/FileLoadResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,31 @@

namespace ExtensionBridge
{
/// <summary>
/// Wraps the result of an attempt to load a file as assembly.
/// </summary>
public class FileLoadResult
{
/// <summary>
/// Create a new instance for a loaded file.
/// </summary>
/// <param name="path">Path to the file/assembly.</param>
/// <param name="e">exception thrown while loading the assembly / null if no exception occurred</param>
public FileLoadResult(string path, Exception e)
{
Exception = e;
FilePath = path;
}

/// <summary>
/// Create a new instance for a successfully loaded file.
/// </summary>
/// <param name="path">Path to the file/assembly.</param>
public FileLoadResult(string path) : this(path, null) { }

/// <summary>
/// True if the file was loaded successfully, false otherwise.
/// </summary>
public bool IsSuccess
{
get
Expand All @@ -24,8 +39,17 @@ public bool IsSuccess
}
}

/// <summary>
/// Path to the file.
/// </summary>
/// <remarks>
/// This path may be local or remote and may not even exist.
/// </remarks>
public string FilePath { get; private set; }

/// <summary>
/// Gets the exception that was thrown while loading the file as assembly. Null iif no exception was thrown.
/// </summary>
public Exception Exception { get; private set; }
}
}
6 changes: 6 additions & 0 deletions ExtensionBridge/IAssemblySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

namespace ExtensionBridge
{
/// <summary>
/// Provides assemblies for extension-lookup.
/// </summary>
/// <seealso cref="KnownAssemblySource"/>
/// <seealso cref="DirectoryAssemblySource"/>
/// <seealso cref="LocalAssemblySource"/>
public interface IAssemblySource
{
/// <summary>
Expand Down
10 changes: 10 additions & 0 deletions ExtensionBridge/KnownAssemblySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@ namespace ExtensionBridge
/// </summary>
public class KnownAssemblySource : IAssemblySource
{
/// <summary>
/// Create a new KnownAssemblySource instance using a known assembly.
/// </summary>
/// <param name="assembly">Assembly which will be provided as source for extension-lookups</param>
public KnownAssemblySource(Assembly assembly)
{
if (assembly.ReflectionOnly) { throw new ArgumentException("assembly is loaded into reflection-only context and not execution-context."); }

Assembly = assembly;
}

/// <summary>
/// Assembly provided as source
/// </summary>
public Assembly Assembly { get; private set; }

/// <inheritdoc/>
public IEnumerable<Assembly> GetAssemblies()
{
return new Assembly[] { Assembly };
Expand Down
6 changes: 5 additions & 1 deletion ExtensionBridge/LocalAssemblySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
namespace ExtensionBridge
{
/// <summary>
/// Uses the currently executing assembly as source for extensions.
/// Uses the entry assembly as source for extensions.
/// </summary>
public class LocalAssemblySource : IAssemblySource
{
/// <summary>
/// Create a new LocalAssemblySource instance.
/// </summary>
public LocalAssemblySource() { }

/// <inheritdoc/>
public IEnumerable<Assembly> GetAssemblies()
{
return new Assembly[] { Assembly.GetEntryAssembly() };
Expand Down
15 changes: 14 additions & 1 deletion ExtensionBridge/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,26 @@

namespace ExtensionBridge
{
/// <summary>
/// Provides extensions based on implemented contracts.
/// </summary>
public class Repository
{
/// <summary>
/// Create a new Repository instance with an empty <see cref="Sources"/> collection.
/// </summary>
public Repository()
{
_Sources = new LinkedList<IAssemblySource>();
}

/// <summary>
/// Create a new Repository instance with a given <see cref="Sources"/> collection.
/// </summary>
/// <param name="sources">sources</param>
/// <remarks>
/// The contents of the <paramref name="sources"/> parameter are copied into a new collection.
/// </remarks>
public Repository(IEnumerable<IAssemblySource> sources)
{
_Sources = new LinkedList<IAssemblySource>(sources);
Expand Down Expand Up @@ -61,7 +74,7 @@ public IEnumerable<Extension<TContract>> GetExtensions<TContract>() 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...
Expand Down

0 comments on commit b5c07d9

Please sign in to comment.