Skip to content

Commit

Permalink
feat: add abstract DependencyConsumer base class for DI consumers (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonisavo committed Sep 21, 2023
1 parent 81ffa33 commit 5fa1979
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions Core/DependencyInjection/DependencyAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace UIComponents
/// </summary>
/// <seealso cref="UIComponent"/>
/// <seealso cref="IDependencyConsumer"/>
/// <seealso cref="DependencyConsumer"/>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = true)]
[ExcludeFromCoverage]
[BaseTypeRequired(typeof(IDependencyConsumer))]
Expand Down
67 changes: 67 additions & 0 deletions Core/DependencyInjection/DependencyConsumer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;

namespace UIComponents.DependencyInjection
{
/// <summary>
/// An abstract base class for classes which want to access
/// UIComponents's dependency injection system.
/// <example>
/// <code>
/// [Dependency(typeof(IMyDependency), provide: typeof(MyDependency))]
/// public class MyClass : DependencyConsumer
/// {
/// [Provide]
/// private IMyDependency _myDependency;
/// }
/// </code>
/// </example>
/// <seealso cref="DependencyAttribute"/>
/// <seealso cref="ProvideAttribute"/>
/// </summary>
public abstract class DependencyConsumer : IDependencyConsumer
{
private static readonly IDependency[] EmptyDependencies = Array.Empty<IDependency>();

private readonly DependencyInjector _dependencyInjector;

internal DependencyConsumer()
{
DiContext.Current.RegisterConsumer(this);
_dependencyInjector = DiContext.Current.GetInjector(GetType());

// ReSharper disable once VirtualMemberCallInConstructor
UIC_PopulateProvideFields();
}

/// <summary>
/// Returns a dependency. Throws a <see cref="MissingProviderException"/>
/// if the dependency can not be provided.
/// </summary>
/// <typeparam name="T">Dependency type</typeparam>
/// <exception cref="MissingProviderException">
/// Thrown if the dependency can not be provided
/// </exception>
/// <returns>Dependency instance</returns>
protected T Provide<T>() where T : class
{
return _dependencyInjector.Provide<T>();
}

/// <summary>
/// Attempts to provide a dependency. Returns whether
/// the dependency could be provided.
/// </summary>
/// <param name="instance">Dependency instance</param>
/// <typeparam name="T">Dependency type</typeparam>
/// <returns>Whether the dependency could be fetched</returns>
protected bool TryProvide<T>(out T instance) where T : class
{
return _dependencyInjector.TryProvide(out instance);
}

public virtual IEnumerable<IDependency> GetDependencies() => EmptyDependencies;

protected virtual void UIC_PopulateProvideFields() {}
}
}
3 changes: 3 additions & 0 deletions Core/DependencyInjection/DependencyConsumer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Core/UIComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ protected UIComponent()
_dependencyInjector = DiContext.Current.GetInjector(GetType());
AssetResolver = Provide<IAssetResolver>();
Logger = Provide<ILogger>();
// ReSharper disable once VirtualMemberCallInConstructor
UIC_PopulateProvideFields();

DependencySetupProfilerMarker.End();
Expand Down

0 comments on commit 5fa1979

Please sign in to comment.