-
-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Description
My usecase is that the ILoggerFactory is build as part of startup and I want to lazy create it until the first ILogger is needed.
I modified the extension
public class LoggingExtension : UnityContainerExtension,
IBuildPlanCreatorPolicy,
IBuildPlanPolicy
{
#region Fields
private readonly MethodInfo _createLoggerMethod = typeof(LoggingExtension).GetTypeInfo()
.GetDeclaredMethod(nameof(CreateLogger));
#endregion
#region Constructors
//[InjectionConstructor]
//public LoggingExtension()
//{
// LoggerFactory = new LoggerFactory();
//}
//public LoggingExtension(ILoggerFactory factory)
//{
// LoggerFactory = factory ?? new LoggerFactory();
//}
#endregion
#region Public Members
//public ILoggerFactory LoggerFactory { get; }
#endregion
#region IBuildPlanPolicy
public void BuildUp(IBuilderContext context)
{
context.Existing = null == context.ParentContext
? context.ParentContext.Container.Resolve<ILoggerFactory>().CreateLogger(context.OriginalBuildKey.Name ?? string.Empty)
: context.Container.Resolve<ILoggerFactory>().CreateLogger(context.ParentContext.BuildKey.Type);
context.BuildComplete = true;
}
#endregion
#region IBuildPlanCreatorPolicy
IBuildPlanPolicy IBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, INamedType buildKey)
{
var info = (context ?? throw new ArgumentNullException(nameof(context))).BuildKey
.Type
.GetTypeInfo();
if (!info.IsGenericType) return this;
var buildMethod = _createLoggerMethod.MakeGenericMethod(info.GenericTypeArguments.First())
.CreateDelegate(typeof(DynamicBuildPlanMethod));
return new DynamicMethodBuildPlan((DynamicBuildPlanMethod)buildMethod, context.Container.Resolve<ILoggerFactory>());
}
#endregion
#region Implementation
private static void CreateLogger<T>(IBuilderContext context, ILoggerFactory loggerFactory)
{
context.Existing = loggerFactory.CreateLogger<T>();
context.BuildComplete = true;
}
protected override void Initialize()
{
Context.Policies.Set(typeof(ILogger), string.Empty, typeof(IBuildPlanPolicy), this);
Context.Policies.Set<IBuildPlanCreatorPolicy>(this, typeof(ILogger));
Context.Policies.Set<IBuildPlanCreatorPolicy>(this, typeof(ILogger<>));
}
private delegate void DynamicBuildPlanMethod(IBuilderContext context, ILoggerFactory loggerFactory);
private class DynamicMethodBuildPlan : IBuildPlanPolicy
{
private readonly DynamicBuildPlanMethod _buildMethod;
private readonly ILoggerFactory _loggerFactory;
/// <summary>
///
/// </summary>
/// <param name="buildMethod"></param>
/// <param name="loggerFactory"></param>
public DynamicMethodBuildPlan(DynamicBuildPlanMethod buildMethod,
ILoggerFactory loggerFactory)
{
_buildMethod = buildMethod;
_loggerFactory = loggerFactory;
}
/// <summary>
///
/// </summary>
/// <param name="context"></param>
public void BuildUp(IBuilderContext context)
{
_buildMethod(context, _loggerFactory);
}
}
#endregion
}
What do you think, should we consider resolving it instead of giving it when constructing the extension?
Metadata
Metadata
Assignees
Labels
No labels