Skip to content

Commit

Permalink
Add doc comments to public apis (#111)
Browse files Browse the repository at this point in the history
YairHalberstadt authored Apr 12, 2021

Verified

This commit was signed with the committer’s verified signature.
renovate-bot Mend Renovate
1 parent a361ba1 commit 0392d5a
Showing 15 changed files with 150 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -6,7 +6,9 @@
<NoWarn>CS1591</NoWarn>
<WarningsNotAsErrors>AD0001</WarningsNotAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<AnalysisLevel>5</AnalysisLevel>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<AnalysisLevel>preview</AnalysisLevel>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<StrongInjectSampleVersion>*-*</StrongInjectSampleVersion>
<StrongInjectExtensionsDependenInjectionSampleVersion>*-*</StrongInjectExtensionsDependenInjectionSampleVersion>
</PropertyGroup>
6 changes: 6 additions & 0 deletions StrongInject/DecoratorFactoryAttribute.cs
Original file line number Diff line number Diff line change
@@ -2,6 +2,12 @@

namespace StrongInject
{
/// <summary>
/// Use this to mark a method as a decorater for it's return type.
/// Exactly one of the parameters must be the same type as the return type.
/// When resolving an instance of the return type, once the type has been resolved as normal it will be passed as a parameter to the method.
/// You can mark both normal methods and generic methods with this attribute.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class DecoratorFactoryAttribute : Attribute
{
9 changes: 9 additions & 0 deletions StrongInject/FactoryAttribute.cs
Original file line number Diff line number Diff line change
@@ -2,9 +2,18 @@

namespace StrongInject
{
/// <summary>
/// Use this to mark a method as a factory.
/// The method will be used to resolve instances of its return type.
/// You can mark both normal methods and generic methods with this attribute.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class FactoryAttribute : Attribute
{
/// <summary>
///
/// </summary>
/// <param name="scope">The scope of each instance resolved from the method - i.e. how often the method will be called.</param>
public FactoryAttribute(Scope scope = Scope.InstancePerResolution)
{
Scope = scope;
11 changes: 11 additions & 0 deletions StrongInject/FactoryOfAttribute.cs
Original file line number Diff line number Diff line change
@@ -2,9 +2,20 @@

namespace StrongInject
{
/// <summary>
/// Use this to mark a generic method as a factory, but only to be used to resolve instances of <see cref="Type"/>.
/// <see cref="Type"/> can be a concrete type or an open generic.
/// You can mark a method with this attribute multiple times.
/// Do not also mark it with the <see cref="FactoryAttribute"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public sealed class FactoryOfAttribute : Attribute
{
/// <summary>
///
/// </summary>
/// <param name="type">The type which the method should be used to resolve</param>
/// <param name="scope">The scope of each instance resolved from the method - i.e. how often the method will be called.</param>
public FactoryOfAttribute(Type type, Scope scope = Scope.InstancePerResolution)
{
Type = type;
4 changes: 4 additions & 0 deletions StrongInject/Helpers.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;

namespace StrongInject
{
[EditorBrowsable(EditorBrowsableState.Never)]
public static class Helpers
{
[EditorBrowsable(EditorBrowsableState.Never)]
public static void Dispose<T>(T instance)
{
if (instance is IDisposable disposable)
@@ -13,6 +16,7 @@ public static void Dispose<T>(T instance)
}
}

[EditorBrowsable(EditorBrowsableState.Never)]
public static ValueTask DisposeAsync<T>(T instance)
{
if (instance is IAsyncDisposable asyncDisposable)
7 changes: 7 additions & 0 deletions StrongInject/IContainer.cs
Original file line number Diff line number Diff line change
@@ -4,13 +4,20 @@

namespace StrongInject
{
/// <summary>
/// Implement this interface to tell StrongInject to generate implementations for <see cref="Run"/> and <see cref="Resolve"/>.
/// You can implement this interface multiple times for different values of <typeparamref name="T"/>, and Single Instances will be shared.
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IContainer<T> : IDisposable
{
[EditorBrowsable(EditorBrowsableState.Never)]
TResult Run<TResult, TParam>(Func<T, TParam, TResult> func, TParam param);
Owned<T> Resolve();
}

/// Implement this interface to tell StrongInject to generate implementations for <see cref="RunAsync"/> and <see cref="ResolveAsync"/>.
/// You can implement this interface multiple times for different values of <typeparamref name="T"/>, and Single Instances will be shared.
public interface IAsyncContainer<T> : IAsyncDisposable
{
[EditorBrowsable(EditorBrowsableState.Never)]
24 changes: 24 additions & 0 deletions StrongInject/IFactory.cs
Original file line number Diff line number Diff line change
@@ -2,6 +2,18 @@

namespace StrongInject
{
/// <summary>
/// A type implementing this interface can be registered as a factory for <typeparamref name="T"/>.
/// It can be registered either via the <see cref="RegisterFactoryAttribute"/>,
/// or by marking a field/property with the <see cref="InstanceAttribute"/> and configuring it's <see cref="InstanceAttribute.Options"/>.
///
/// In general it's easier to use factory methods instead (methods marked with the <see cref="FactoryAttribute"/>.
/// Only use this if you either need control over the lifetime of the factory,
/// or you need to control disposal of the created type.
///
/// For example, you may want to implement this if you would like to cache and reuse instances after they've been released.
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IFactory<T>
{
T Create();
@@ -13,6 +25,18 @@ void Release(T instance)
;
}

/// <summary>
/// A type implementing this interface can be registered as an async factory for <typeparamref name="T"/>.
/// It can be registered either via the <see cref="RegisterFactoryAttribute"/>,
/// or by marking a field/property with the <see cref="InstanceAttribute"/> and configuring it's <see cref="InstanceAttribute.Options"/>.
///
/// In general it's easier to use factory methods instead (methods marked with the <see cref="FactoryAttribute"/>.
/// Only use this if you either need control over the lifetime of the factory,
/// or you need to control disposal of the created type.
///
/// For example, you may want to implement this if you would like to cache and reuse instances after they've been released.
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IAsyncFactory<T>
{
ValueTask<T> CreateAsync();
6 changes: 6 additions & 0 deletions StrongInject/IRequiresInitialization.cs
Original file line number Diff line number Diff line change
@@ -2,11 +2,17 @@

namespace StrongInject
{
/// <summary>
/// Implement this interface to inform StrongInject that a type will need initialization once it is instantiated before it is ready to be used.
/// </summary>
public interface IRequiresInitialization
{
void Initialize();
}

/// <summary>
/// Implement this interface to inform StrongInject that a type will need asynchronous initialization once it is instantiated before it is ready to be used.
/// </summary>
public interface IRequiresAsyncInitialization
{
ValueTask InitializeAsync();
8 changes: 8 additions & 0 deletions StrongInject/InstanceAttribute.cs
Original file line number Diff line number Diff line change
@@ -2,9 +2,17 @@

namespace StrongInject
{
/// <summary>
/// Use this attribute to register a field or property, so it can be used in resolution.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class InstanceAttribute : Attribute
{
/// <summary>
///
/// </summary>
/// <param name="options">Options to configure how the field/property should be registered.
/// See the documentation on <see cref="StrongInject.Options"/>.</param>
public InstanceAttribute(Options options = Options.Default)
{
Options = options;
20 changes: 20 additions & 0 deletions StrongInject/Owned.cs
Original file line number Diff line number Diff line change
@@ -4,6 +4,16 @@

namespace StrongInject
{
/// <summary>
/// A disposable wrapper for an instance of <typeparamref name="T"/>.
///
/// Make sure to dispose this once you are done using <see cref="Value"/>. This will dispose <see cref="Value"/> and all dependencies of it.
///
/// Do not dispose <see cref="Value"/> directly as that will not dispose its dependencies.
///
/// Do not use <see cref="Value"/> after this is disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class Owned<T> : IDisposable
{
private readonly Action _dispose;
@@ -27,6 +37,16 @@ public void Dispose()
}
}

/// <summary>
/// An async disposable wrapper for an instance of <typeparamref name="T"/>.
///
/// Make sure to dispose this once you are done using <see cref="Value"/>. This will dispose <see cref="Value"/> and all dependencies of it.
///
/// Do not dispose <see cref="Value"/> directly as that will not dispose its dependencies.
///
/// Do not use <see cref="Value"/> after this is disposed.
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class AsyncOwned<T> : IAsyncDisposable
{
private readonly Func<ValueTask> _dispose;
22 changes: 22 additions & 0 deletions StrongInject/RegisterAttribute.cs
Original file line number Diff line number Diff line change
@@ -2,13 +2,35 @@

namespace StrongInject
{
/// <summary>
/// Use this attribute to register a type with StrongInject.
/// The type must have either exactly one public constructor, or exactly two public constructors, one of which is parameterless.
/// By default the type will be registered as an instance of itself. You can modify it to be registered as any of its supertypes.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public sealed class RegisterAttribute : Attribute
{
/// <summary>
///
/// </summary>
/// <param name="type">The type to be registered</param>
/// <param name="registerAs">An optional list of types for it to be registered as an instance of.
/// If left empty it will be registered as itself.
/// If not left empty you will have to explicitly register it as itself if desired.
/// All types must be supertypes of <paramref name="type"/></param>
public RegisterAttribute(Type type, params Type[] registerAs) : this(type, Scope.InstancePerResolution, registerAs)
{
}

/// <summary>
///
/// </summary>
/// <param name="type">The type to be registered</param>
/// <param name="scope">The scope of each instance of <paramref name="type"/> - i.e. how often will a new instance be created.</param>
/// <param name="registerAs">An optional list of types for it to be registered as an instance of.
/// If left empty it will be registered as itself.
/// If not left empty you will have to explicitly register it as itself if desired.
/// All types must be supertypes of</param>
public RegisterAttribute(Type type, Scope scope, params Type[] registerAs)
{
Type = type;
10 changes: 10 additions & 0 deletions StrongInject/RegisterDecoratorAttribute.cs
Original file line number Diff line number Diff line change
@@ -2,9 +2,19 @@

namespace StrongInject
{
/// <summary>
/// Use this attribute to register a decorator for a type.
/// When resolving an instance of the type, once the type has been resolved as normal it will be wrapped by an instance of the decorator.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public sealed class RegisterDecoratorAttribute : Attribute
{
/// <summary>
///
/// </summary>
/// <param name="type">The type to use as a decorator. Must be a subtype of <paramref name="decoratedType"/>.</param>
/// <param name="decoratedType">The type which will be decorated (wrapped) by <paramref name="type"/>.</param>
/// <param name="decoratorOptions"></param>
public RegisterDecoratorAttribute(Type type, Type decoratedType, DecoratorOptions decoratorOptions = DecoratorOptions.Default)
{
Type = type;
13 changes: 13 additions & 0 deletions StrongInject/RegisterFactoryAttribute.cs
Original file line number Diff line number Diff line change
@@ -2,9 +2,22 @@

namespace StrongInject
{
/// <summary>
/// Use this attribute to register a type implementing <see cref="IFactory{T}"/> or <see cref="IAsyncFactory{T}"/> as a factory for T,
/// meaning T will be resolved by resolving an instance of the factory, and then calling <see cref="IFactory{T}.Create"/> or <see cref="IAsyncFactory{T}.CreateAsync"/>.
///
/// It's usually simpler to write a factory method and mark it with the <see cref="FactoryAttribute"/>.
/// Use this only if you need tight control over the lifetime of your factory, or if you want to control disposal of the factory target.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public sealed class RegisterFactoryAttribute : Attribute
{
/// <summary>
///
/// </summary>
/// <param name="factoryType">The factory to register. Must implement <see cref="IFactory{T}"/> or <see cref="IAsyncFactory{T}"/>.</param>
/// <param name="factoryScope">The scope of the factory - i.e. how often should a new factory be created?</param>
/// <param name="factoryTargetScope">The scope of the factory target - i.e. how often should <see cref="IFactory{T}.Create"/> or <see cref="IAsyncFactory{T}.CreateAsync"/> be called?</param>
public RegisterFactoryAttribute(Type factoryType, Scope factoryScope = Scope.InstancePerResolution, Scope factoryTargetScope = Scope.InstancePerResolution)
{
FactoryType = factoryType;
6 changes: 6 additions & 0 deletions StrongInject/RegisterModuleAttribute.cs
Original file line number Diff line number Diff line change
@@ -2,9 +2,15 @@

namespace StrongInject
{
/// <summary>
/// Use this attribute to import registrations defined on a different type.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public sealed class RegisterModuleAttribute : Attribute
{
/// <summary/>
/// <param name="type">The module to register</param>
/// <param name="exclusionList">An optional list of types which should not be resolved via this module</param>
public RegisterModuleAttribute(Type type, params Type[] exclusionList)
{
Type = type;
2 changes: 1 addition & 1 deletion StrongInject/ValueTaskExtensions.cs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

namespace StrongInject
{
public static class ValueTaskExtensions
internal static class ValueTaskExtensions
{
public static ValueTask AsValueTask<T>(this ValueTask<T> valueTask)
{

0 comments on commit 0392d5a

Please sign in to comment.