diff --git a/src/Microsoft.Performance.SDK.Runtime.NetCoreApp/Plugins/PluginsLoader.cs b/src/Microsoft.Performance.SDK.Runtime.NetCoreApp/Plugins/PluginsLoader.cs index 315472d8..58bcb639 100644 --- a/src/Microsoft.Performance.SDK.Runtime.NetCoreApp/Plugins/PluginsLoader.cs +++ b/src/Microsoft.Performance.SDK.Runtime.NetCoreApp/Plugins/PluginsLoader.cs @@ -109,7 +109,7 @@ public PluginsLoader( // The constructor for this object hooks up the repository to the extension provider // (the ExtensionDiscovery in this case). We do not need to hold onto this object // explicitly, only call its constructor. - new DataExtensionReflector(this.extensionDiscovery, extensionRepository); + new DataExtensionReflector(this.extensionDiscovery, extensionRepository, logger); this.isDisposed = false; this.logger = logger; @@ -254,7 +254,7 @@ public bool TryLoadPlugins(IEnumerable directories, out IDictionary(); if (!directories.Any()) @@ -280,21 +280,21 @@ public bool TryLoadPlugins(IEnumerable directories, out IDictionary /// Tries to create an instance of based on the /// . @@ -69,10 +70,7 @@ internal static bool TryCreateReference( Type candidateType, out ICompositeDataCookerReference reference) { - return TryCreateReference( - candidateType, - Runtime.Logger.Create(), - out reference); + return TryCreateReference(candidateType, null, out reference); } /// @@ -105,11 +103,15 @@ internal static bool TryCreateReference( ILogger logger, out ICompositeDataCookerReference reference) { - Guard.NotNull(candidateType, nameof(candidateType)); - Guard.NotNull(logger, nameof(logger)); + Debug.Assert(candidateType != null, $"{nameof(candidateType)} cannot be null."); reference = null; + if (logger == null) + { + logger = Runtime.Logger.Create(); + } + if (candidateType.IsInstantiatableOfType(typeof(ICompositeDataCookerDescriptor))) { // There must be an empty, public constructor diff --git a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataCookers/SourceDataCookerReference.cs b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataCookers/SourceDataCookerReference.cs index 382cc5d4..2b7baf94 100644 --- a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataCookers/SourceDataCookerReference.cs +++ b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataCookers/SourceDataCookerReference.cs @@ -10,7 +10,6 @@ using Microsoft.Performance.SDK.Extensibility.DataCooking; using Microsoft.Performance.SDK.Extensibility.DataCooking.SourceDataCooking; using Microsoft.Performance.SDK.Processing; -using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataProcessors; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.Dependency; namespace Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataCookers @@ -139,10 +138,7 @@ internal static bool TryCreateReference( Type candidateType, out ISourceDataCookerReference reference) { - return TryCreateReference( - candidateType, - Runtime.Logger.Create(), - out reference); + return TryCreateReference(candidateType, null, out reference); } /// @@ -176,10 +172,15 @@ internal static bool TryCreateReference( ILogger logger, out ISourceDataCookerReference reference) { - Guard.NotNull(candidateType, nameof(candidateType)); + Debug.Assert(candidateType != null, $"{nameof(candidateType)} cannot be null."); reference = null; + if (logger == null) + { + logger = Runtime.Logger.Create(); + } + // perform this basic check first, as it's cheaper than a more specific test below if (!candidateType.Implements(typeof(IDataCooker))) { @@ -202,7 +203,7 @@ internal static bool TryCreateReference( // There must be an empty, public constructor if (!candidateType.TryGetEmptyPublicConstructor(out var constructor)) { - Console.Error.WriteLine( + logger.Error( $"Warning: type {candidateType} seems to be a data cooker, but is missing an empty public " + "constructor."); return false; diff --git a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataExtensionFactory.cs b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataExtensionFactory.cs index 4580d9a9..3c79c222 100644 --- a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataExtensionFactory.cs +++ b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataExtensionFactory.cs @@ -7,7 +7,6 @@ using Microsoft.Performance.SDK.Extensibility.SourceParsing; using Microsoft.Performance.SDK.Processing; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataCookers; -using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataProcessors; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.Repository; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.Tables; @@ -19,13 +18,13 @@ namespace Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions public class DataExtensionFactory : IDataExtensionFactory { - private static readonly DataExtensionRepository SingletonRepository + private static readonly DataExtensionRepository SingletonRepository = new DataExtensionRepository(); /// /// Gets a singleton instance of this class. /// - public IDataExtensionRepositoryBuilder SingletonDataExtensionRepository + public IDataExtensionRepositoryBuilder SingletonDataExtensionRepository => DataExtensionFactory.SingletonRepository; /// @@ -43,10 +42,33 @@ public IDataExtensionRepositoryBuilder SingletonDataExtensionRepository public bool TryCreateSourceDataCookerReference( Type candidateType, out ISourceDataCookerReference reference) + { + return TryCreateSourceDataCookerReference(candidateType, null, out reference); + } + + /// + /// Generate a source data cooker reference from a given type. + /// + /// + /// Data extension type. + /// + /// + /// Data extension reference. + /// + /// + /// Logs messages during reference creation. + /// + /// + /// true if succeeded, false otherwise. + /// + public bool TryCreateSourceDataCookerReference( + Type candidateType, + ILogger logger, + out ISourceDataCookerReference reference) { Guard.NotNull(candidateType, nameof(candidateType)); - return SourceDataCookerReference.TryCreateReference(candidateType, out reference); + return SourceDataCookerReference.TryCreateReference(candidateType, logger, out reference); } /// @@ -64,10 +86,33 @@ public bool TryCreateSourceDataCookerReference( public bool TryCreateCompositeDataCookerReference( Type candidateType, out ICompositeDataCookerReference reference) + { + return TryCreateCompositeDataCookerReference(candidateType, null, out reference); + } + + /// + /// Generate a composite data cooker reference from a given type. + /// + /// + /// Data extension type. + /// + /// + /// Logs messages during reference creation. + /// + /// + /// Data extension reference. + /// + /// + /// true if succeeded, false otherwise. + /// + public bool TryCreateCompositeDataCookerReference( + Type candidateType, + ILogger logger, + out ICompositeDataCookerReference reference) { Guard.NotNull(candidateType, nameof(candidateType)); - return CompositeDataCookerReference.TryCreateReference(candidateType, out reference); + return CompositeDataCookerReference.TryCreateReference(candidateType, logger, out reference); } // TODO: __SDK_DP__ @@ -108,10 +153,33 @@ public bool TryCreateCompositeDataCookerReference( public bool TryCreateTableReference( Type candidateType, out ITableExtensionReference reference) + { + return TryCreateTableReference(candidateType, null, out reference); + } + + /// + /// Generate a table reference from a given type. + /// + /// + /// Data extension type. + /// + /// + /// Logs messages during reference creation. + /// + /// + /// Data extension reference. + /// + /// + /// true if succeeded, false otherwise. + /// + public bool TryCreateTableReference( + Type candidateType, + ILogger logger, + out ITableExtensionReference reference) { Guard.NotNull(candidateType, nameof(candidateType)); - return TableExtensionReference.TryCreateReference(candidateType, out reference); + return TableExtensionReference.TryCreateReference(candidateType, logger, out reference); } /// diff --git a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataExtensionReflector.cs b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataExtensionReflector.cs index a6a2f660..7e0d3154 100644 --- a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataExtensionReflector.cs +++ b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/DataExtensionReflector.cs @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using System; +using System.Diagnostics; +using Microsoft.Performance.SDK.Processing; using Microsoft.Performance.SDK.Runtime.Discovery; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataCookers; -using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataProcessors; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.Repository; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.Tables; -using System; -using System.Diagnostics; namespace Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions { @@ -18,6 +18,7 @@ public class DataExtensionReflector : IExtensionTypeObserver { private readonly IDataExtensionRepositoryBuilder repoBuilder; + private readonly ILogger logger; /// /// Initializes a new instance of the DataExtensionReflector class. @@ -28,11 +29,17 @@ public class DataExtensionReflector /// /// Provides an output to store discovered extensions. /// + /// + /// Logs messages during reference creation. + /// public DataExtensionReflector( IExtensionTypeProvider extensionProvider, - IDataExtensionRepositoryBuilder repoBuilder) + IDataExtensionRepositoryBuilder repoBuilder, + ILogger logger) { this.repoBuilder = repoBuilder; + this.logger = logger; + extensionProvider.RegisterTypeConsumer(this); } @@ -40,21 +47,21 @@ public DataExtensionReflector( public void ProcessType(Type type, string sourceName) { // Find source data cookers - if (SourceDataCookerReference.TryCreateReference(type, out var sourceDataCookerReference)) + if (SourceDataCookerReference.TryCreateReference(type, this.logger, out var sourceDataCookerReference)) { Debug.Assert(sourceDataCookerReference != null); this.repoBuilder.AddSourceDataCookerReference(sourceDataCookerReference); } // Find composite data cookers - if (CompositeDataCookerReference.TryCreateReference(type, out var compositeDataCookerReference)) + if (CompositeDataCookerReference.TryCreateReference(type, this.logger, out var compositeDataCookerReference)) { Debug.Assert(compositeDataCookerReference != null); this.repoBuilder.AddCompositeDataCookerReference(compositeDataCookerReference); } // Find tables - if (TableExtensionReference.TryCreateReference(type, out var dataExtensionReference)) + if (TableExtensionReference.TryCreateReference(type, this.logger, out var dataExtensionReference)) { Debug.Assert(dataExtensionReference != null); this.repoBuilder.AddTableExtensionReference(dataExtensionReference); diff --git a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/IDataExtensionFactory.cs b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/IDataExtensionFactory.cs index 2ce67faf..3ebf574d 100644 --- a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/IDataExtensionFactory.cs +++ b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/IDataExtensionFactory.cs @@ -7,7 +7,6 @@ using Microsoft.Performance.SDK.Extensibility.SourceParsing; using Microsoft.Performance.SDK.Processing; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataCookers; -using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataProcessors; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.Repository; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.Tables; @@ -39,6 +38,45 @@ bool TryCreateSourceDataCookerReference( Type candidateType, out ISourceDataCookerReference reference); + /// + /// Generate a source data cooker reference from a given type. + /// + /// + /// data extension type. + /// + /// + /// Logs messages during reference creation. + /// + /// + /// data extension reference. + /// + /// + /// true if succeeded. + /// + bool TryCreateSourceDataCookerReference( + Type candidateType, + ILogger logger, + out ISourceDataCookerReference reference); + + /// + /// Generate a composite data cooker reference from a given type. + /// + /// + /// data extension type + /// + /// Logs messages during reference creation. + /// + /// + /// Data extension reference. + /// + /// + /// true if succeeded. + /// + bool TryCreateCompositeDataCookerReference( + Type candidateType, + ILogger logger, + out ICompositeDataCookerReference reference); + /// /// Generate a composite data cooker reference from a given type. /// @@ -88,6 +126,26 @@ bool TryCreateTableReference( Type candidateType, out ITableExtensionReference reference); + /// + /// Generate a table reference from a given type. + /// + /// + /// data extension type. + /// + /// + /// data extension reference. + /// + /// + /// Logs messages during reference creation. + /// + /// + /// true if succeeded. + /// + bool TryCreateTableReference( + Type candidateType, + ILogger logger, + out ITableExtensionReference reference); + /// /// Creates a data extension repository. /// diff --git a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/Tables/TableExtensionReference.cs b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/Tables/TableExtensionReference.cs index 07370c36..d9357ee2 100644 --- a/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/Tables/TableExtensionReference.cs +++ b/src/Microsoft.Performance.SDK.Runtime/Extensibility/DataExtensions/Tables/TableExtensionReference.cs @@ -148,13 +148,57 @@ internal static bool TryCreateReference( Type candidateType, out ITableExtensionReference reference) { - Guard.NotNull(candidateType, nameof(candidateType)); + return TryCreateReference(candidateType, null, out reference); + } + + /// + /// Tries to create an instance of based on the + /// . + /// + /// A must satisfy the following criteria in order to + /// be eligible as a reference: + /// + /// + /// must expose a valid . + /// See + /// for details on how a table is to expose a descriptor. + /// + /// + /// + /// + /// Candidate for the + /// + /// + /// Logs messages during reference creation. + /// + /// + /// Out + /// + /// + /// true if the is valid and can create a instance of ; + /// false otherwise. + /// + /// + /// is null. + /// + internal static bool TryCreateReference( + Type candidateType, + ILogger logger, + out ITableExtensionReference reference) + { + Debug.Assert(candidateType != null, $"{nameof(candidateType)} cannot be null."); reference = null; + if (logger == null) + { + logger = Logger.Create(); + } + if (TableDescriptorFactory.TryCreate( candidateType, tableConfigSerializer, + logger, out var tableDescriptor, out var tableBuildAction, out var tableIsDataAvailableFunc)) diff --git a/src/Microsoft.Performance.SDK.Runtime/SourceDataCookerReferenceFactory.cs b/src/Microsoft.Performance.SDK.Runtime/SourceDataCookerReferenceFactory.cs index bc64708f..3543098a 100644 --- a/src/Microsoft.Performance.SDK.Runtime/SourceDataCookerReferenceFactory.cs +++ b/src/Microsoft.Performance.SDK.Runtime/SourceDataCookerReferenceFactory.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using Microsoft.Performance.SDK.Processing; using Microsoft.Performance.SDK.Runtime.Extensibility.DataExtensions.DataCookers; namespace Microsoft.Performance.SDK.Runtime @@ -31,7 +32,36 @@ public static bool TryCreateReference( Type candidateType, out ISourceDataCookerReference reference) { - return SourceDataCookerReference.TryCreateReference(candidateType, out reference); + return TryCreateReference(candidateType, null, out reference); + } + + /// + /// Creates an for a given type. + /// + /// + /// This will not add the generated reference to a cooker repository, and the cooker's data will not be + /// available through the standard cooker framework. + /// + /// + /// Type that represents a source data cooker. + /// + /// + /// Logs messages during reference creation. + /// + /// + /// A reference to a source data cooker for the given type. + /// + /// + /// true if a reference was generated; otherwise false + /// + public static bool TryCreateReference( + Type candidateType, + ILogger logger, + out ISourceDataCookerReference reference) + { + Guard.NotNull(candidateType, nameof(candidateType)); + + return SourceDataCookerReference.TryCreateReference(candidateType, logger, out reference); } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Performance.Toolkit.Engine/Engine.cs b/src/Microsoft.Performance.Toolkit.Engine/Engine.cs index 89dfe78c..845de335 100644 --- a/src/Microsoft.Performance.Toolkit.Engine/Engine.cs +++ b/src/Microsoft.Performance.Toolkit.Engine/Engine.cs @@ -750,9 +750,12 @@ private static Engine CreateCore(EngineCreateInfo createInfo, DataSourceSet inte { Debug.Assert(createInfo != null); - var loggerFactory = createInfo.LoggerFactory ?? Logger.Create; + if (createInfo.LoggerFactory != null) + { + Logger.Factory = createInfo.LoggerFactory; + } - var logger = loggerFactory(typeof(Engine)); + var logger = Logger.Create(typeof(Engine)); Engine instance = null; try diff --git a/src/Microsoft.Performance.Toolkit.Engine/PluginSet.cs b/src/Microsoft.Performance.Toolkit.Engine/PluginSet.cs index 51348353..01548dd3 100644 --- a/src/Microsoft.Performance.Toolkit.Engine/PluginSet.cs +++ b/src/Microsoft.Performance.Toolkit.Engine/PluginSet.cs @@ -355,7 +355,7 @@ public static PluginSet Load( var factory = new DataExtensionFactory(); repo = factory.CreateDataExtensionRepository(); - var reflector = new DataExtensionReflector(assemblyDiscovery, repo); + var reflector = new DataExtensionReflector(assemblyDiscovery, repo, logger); assemblyDiscovery.ProcessAssemblies(extensionDirectoriesFullPaths, out var discoveryError);