-
Notifications
You must be signed in to change notification settings - Fork 831
Add support for reference to public static properties in settings #1064
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
as a value for parameters, using the syntax `NameSpace.To.ConcreteType::StaticProperty, AssemblyName`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about the slow response; this one's looking good to me, just one thought.
@@ -29,6 +35,22 @@ class SettingValueConversions | |||
|
|||
public static object ConvertToType(string value, Type toType) | |||
{ | |||
if (TryParseStaticMemberAccessor(value, out var accessorTypeName, out var memberName)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this could move down to the if ((toTypeInfo.IsInterface || toTypeInfo.IsAbstract) && !string.IsNullOrWhiteSpace(value))
block? If it's first up, here, we might hit issues where this is ambiguous, e.g. the target Type
is string
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was my initial implementation, but then I thought it would be strange to limit it to only abstract class
es and interface
s, because after all this can also be useful in other cases, like for sinks that accept complex parameters that are not abstract
nor interface
(for instance : EmailConnectionInfo
in Serilog.Sinks.Email , ColumnOptions
for Serilog.Sinks.MSSqlServer ...)
This also gives a workaround for configuration that cannot be easily defined with the key-value settings syntax, by allowing to define it as code in a static property.
Also, I've tried to make the regex for static-property accessor as specific as possible to avoid false positives.
What do you think ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nblumhardt any opinion on the subject? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a fair consideration - just not sure if it's behavior we want to commit to yet in this PR. (We'd also then need to consider whether assembly-qualified type names should be supported in more places, since subclassing is a possible workaround for other scenarios, plus look at how this would interact with some kind of "structure" syntax for populating fields of complex configuration parameters down the track).
TL;DR: I don't think it's a bad idea - just might be scope creep for this PR, since we haven't really dug through all the possible implications :-) .. what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense 👍
Easier to make it support a few use cases initially and extend it later on if needed.
Thanks !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great 👍 just a few thoughts
@@ -29,6 +35,22 @@ class SettingValueConversions | |||
|
|||
public static object ConvertToType(string value, Type toType) | |||
{ | |||
if (TryParseStaticMemberAccessor(value, out var accessorTypeName, out var memberName)) | |||
{ | |||
var accessorType = Type.GetType(accessorTypeName, throwOnError: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably, for a better UX could we also use full type names without specifying assembly? We could look for the target type in configuration assemblies (using
section) something like:
var accessorType = Type.GetType(typeName) ??
_assemblies.SelectMany(a => a.ExportedTypes)
.FirstOrDefault(t => t.FullName == typeName);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do that for members, could/should we do the same thing for instances?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now I've tried to not deviate too much from the way arbitrary sub-types (for interfaces and abstract classes) are referenced, that is with full assembly-qualified type names. Maybe lifting that restriction would be nice, but I would keep it as a separate issue / PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good
{ | ||
var accessorType = Type.GetType(accessorTypeName, throwOnError: true); | ||
var publicStaticPropertyInfo = accessorType.GetTypeInfo().DeclaredProperties | ||
.Where(x => x.Name == memberName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we could also add support for the public static fields at the same time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have mixed feelings about accessing arbitrary fields, but I guess if they are public
, they are part of the public API so technically accessible. I'll include public fields as well. 👍
I've updated my PR with the suggested changes. |
👍 |
as a value for parameters, using the syntax
NameSpace.To.ConcreteType::StaticProperty, AssemblyName
What issue does this PR address?
resolves #1057
Does this PR introduce a breaking change?
It shouldn't, although technically, there is a chance that "string" settings whose value looks like
"Namespace.To.TypeName::PropertyName"
may now be interpreted as a reference to a static property, even though I've done my best to avoid ambiguities.Please check if the PR fulfills these requirements
Other information:
When / if accepted, similar code should be needed in Serilog.Settings.Configuration to handle issue serilog/serilog-settings-configuration#73 .