Skip to content

Commit fd5620f

Browse files
authored
Merge pull request #11 from nblumhardt/master
Support interface types in configuration values
2 parents 2a0ecf8 + 53ca050 commit fd5620f

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

src/Serilog.Settings.Configuration/Properties/AssemblyInfo.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,9 @@
1919
// COM, set the ComVisible attribute to true on that type.
2020
[assembly: ComVisible(false)]
2121

22-
// The following GUID is for the ID of the typelib if this project is exposed to COM
23-
[assembly: Guid("21ff98ed-e68c-4a67-b241-c8d6122fad7d")]
22+
[assembly: InternalsVisibleTo("Serilog.Settings.Configuration.Tests, PublicKey=" +
23+
"0024000004800000940000000602000000240000525341310004000001000100fb8d13fd344a1c" +
24+
"6fe0fe83ef33c1080bf30690765bc6eb0df26ebfdf8f21670c64265b30db09f73a0dea5b3db4c9" +
25+
"d18dbf6d5a25af5ce9016f281014d79dc3b4201ac646c451830fc7e61a2dfd633d34c39f87b818" +
26+
"94191652df5ac63cc40c77f3542f702bda692e6e8a9158353df189007a49da0f3cfd55eb250066" +
27+
"b19485ec")]

src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@ static void CallConfigurationMethods(Dictionary<string, Dictionary<string, strin
183183
}
184184
}
185185

186+
static readonly Dictionary<Type, Func<string, object>> ExtendedTypeConversions = new Dictionary<Type, Func<string, object>>
187+
{
188+
{ typeof(Uri), s => new Uri(s) },
189+
{ typeof(TimeSpan), s => TimeSpan.Parse(s) }
190+
};
191+
192+
186193
internal static object ConvertToType(string value, Type toType)
187194
{
188195
var toTypeInfo = toType.GetTypeInfo();
@@ -199,18 +206,34 @@ internal static object ConvertToType(string value, Type toType)
199206
if (toTypeInfo.IsEnum)
200207
return Enum.Parse(toType, value);
201208

202-
var extendedTypeConversions = new Dictionary<Type, Func<string, object>>
203-
{
204-
{ typeof(Uri), s => new Uri(s) },
205-
{ typeof(TimeSpan), s => TimeSpan.Parse(s) }
206-
};
207-
208-
var convertor = extendedTypeConversions
209+
var convertor = ExtendedTypeConversions
209210
.Where(t => t.Key.GetTypeInfo().IsAssignableFrom(toTypeInfo))
210211
.Select(t => t.Value)
211212
.FirstOrDefault();
212213

213-
return convertor == null ? Convert.ChangeType(value, toType) : convertor(value);
214+
if (convertor != null)
215+
return convertor(value);
216+
217+
if (toTypeInfo.IsInterface && !string.IsNullOrWhiteSpace(value))
218+
{
219+
var type = Type.GetType(value.Trim(), throwOnError: false);
220+
if (type != null)
221+
{
222+
var ctor = type.GetTypeInfo().DeclaredConstructors.FirstOrDefault(ci =>
223+
{
224+
var parameters = ci.GetParameters();
225+
return parameters.Length == 0 || parameters.All(pi => pi.HasDefaultValue);
226+
});
227+
228+
if (ctor == null)
229+
throw new InvalidOperationException($"A default constructor was not found on {type.FullName}.");
230+
231+
var call = ctor.GetParameters().Select(pi => pi.DefaultValue).ToArray();
232+
return ctor.Invoke(call);
233+
}
234+
}
235+
236+
return Convert.ChangeType(value, toType);
214237
}
215238

216239
internal static IList<MethodInfo> FindSinkConfigurationMethods(IEnumerable<Assembly> configurationAssemblies)

0 commit comments

Comments
 (0)