Giter VIP home page Giter VIP logo

namotion.reflection's Introduction

namotion.reflection's People

Contributors

adamjones1 avatar bert2 avatar cfbao avatar cnshenj avatar eerhardt avatar enif-lee avatar gavchen avatar jeremyvignelles avatar lahma avatar nickbranstein avatar productiverage avatar ricosuter avatar scottsauber avatar sebastianstehle avatar simoncropp avatar sprotty avatar swharden avatar t-mxcom avatar thompson-tomo avatar travisez13 avatar yetawf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

namotion.reflection's Issues

Documentation not being created for methods originating in inherited classes

XML documentation placed on (abstract) base controller class does not appear in swagger doc. Only XML documentation applied to the controller class that inherits the base class appears.

    [ApiController]
    public abstract class BaseController : ControllerBase
    {
        /// <summary>
        /// This documentation will not appear in swagger doc
        /// </summary>
        /// <param name="p">This will also not appear in swagger doc</param>
        /// <returns></returns>
        [HttpGet("{p}")]
        public ActionResult Test(int p)
        {
            return Ok();
        }
    }

    /// <summary>
    /// This controller now has a Patch method and an inherited Get method
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class MyController : BaseController
    {
        /// <summary>
        /// This documentation WILL appear in swagger doc
        /// </summary>
        /// <param name="p">This parameter will be documented</param>
        /// <returns></returns>
        [HttpPatch("{p}")]
        public ActionResult Test2(int p)
        {
            return Ok();
        }
    }```

C#
.NET Core 2.2
Visual Studio 2017
NSwag 12.0.14

GetXmlDocsSummary with Blazor Wasm

The method works great for blazor server but not for wasm. Added components as embedded resources but still doesn't work. Did i do something wrong?

problem with EF Core Lazy load Proxy

I created this classes

    [Table("Left")]
    public class Left
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Key]
        public int Id { get; set; }
        [DisallowNull]
        public virtual Child Child { get; set; } = null!;
        public virtual Left? Next { get; set; }
        public virtual IList<Right> Rights { get; set; } = new List<Right>();
    }
    [Table("Child")]
    public class Child
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Key]
        public int Id { get; set; }
    }

    [Table("Right")]
    public class Right
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Key]
        public int Id { get; set; }

        public virtual IList<Left> Lefts { get; set; } = new List<Left>();

    }

And have this problem

var left1 = new Left();
left1.EnsureValidNullability();

This throw the error

If I get from the database I get no error

            var optionsBuilder = new DbContextOptionsBuilder<ModelContext>().UseLazyLoadingProxies()
                .UseSqlServer("Server=.\\sql2019;Database=Nullable;Trusted_Connection=false;user id=sa;pwd=sa;MultipleActiveResultSets=true;Encrypt=false");

using (var context = new ModelContext(optionsBuilder.Options))
{
    var left = context.Left.Find(leftid);


    if (left != null)
    {

        var x = left.Child;
        left.GetType()?.GetProperty("Child")?.SetValue(left, null);
        x = left.Child;

        left.EnsureValidNullability();
}
}

GetXmlDocsSummary fails on methods with Expression parameters whose delegate returns a generic type

Using .NET 4.8 with Namotion.Reflection v2.0.3, if I have a method with a signature like the following:

public void TestMethod(Expression<Func<TModel>> expr)

and then call GetXMLDocsSummary() on a MethodInfo instance for it, the call will return an empty string even when there is an appropriate entry in the XML doc file. However if I change the return of the delegate to a concrete type (e.g. Func<string>>) the summary is returned without issue.

Stepping into the code I can see that GetMemberElementName() is throwing a "Method may only be called on a Type for which Type.IsGenericParameter is true." exception. This occurs at the point where the code iterates the generic type arguments and references GenericParameterPosition. The type in question (the Func) has IsGenericParameter as false (however its GenericTypeArguments has a member with IsGenericParameter true and a valid GenericParameterPosition - perhaps an additional level of indirection is needed?)

Test case code (based on the Namotion.Reflection.Demo sample) is attached.

Program.cs.txt

XmlDocsExtensions.GetXmlDocsSummary fails on <inheritdoc/> and concurrent access

Commit ID: 33e53f6

Steps:

  • XmlDocsExtensions.GetXmlDocsSummary(...) is called for the same member concurrently
  • That member inherits the documentation from a base class/interface
  • Internally, XmlDocsExtensions.TryGetXmlDocsDocument adds an entry to XmlDocsExtensions.Cache with documentation loaded into XElement. This is the first problematic place, because current implementation of TryGetXmlDocsDocument can return different results for the same key. Be result immutable or if every client got own unique result, then there will be no race condition.
  • However, there are few places which modify cached entry (XElement), by replacing with actual content without any kind of synchronization. Obviously, modifying the same XElement tree concurrently makes Linq goes nuts.

The following snippet will fail with an exception thrown by Linq implementation:

    public interface IMyObject
    {
        /// <summary>
        /// Description
        /// </summary>
        void DoSomething();
    }

    public class MyObject : IMyObject
    {
        /// <inheritdoc/>
        public void DoSomething() { }
    }

    internal class Program
    {
        static void Do()
        {
            typeof(MyObject).GetMember(nameof(MyObject.DoSomething)).Single().GetXmlDocsSummary();
        }

        static void Main(string[] args)
        {
            for (int i = 0; ; ++i)
            {
                Console.WriteLine(i);
                var tasks = new[]
                {
                    Task.Run(Do),
                    Task.Run(Do),
                    Task.Run(Do),
                    Task.Run(Do),
                };
                Task.WaitAll(tasks);
                XmlDocs.ClearCache();
            }
        }
    }

In my case, it's about running unit-tests performing a JSON validation using JsonSchema in parallel. JsonSchema is generated on the fly.

EnsureValidNullability does not work with lists of values, whether nullable reference types are allowed or not

It seems that the contents of list types are not correctly checked for null whether or not non-nullable-reference-type behaviour is enabled - for example, the below code will throw a System.NullReferenceException if reference types are allowed to be null or not:

var json = "[ null ]";
var arrayOfString = JsonConvert.DeserializeObject<string[]>(json);
arrayOfString.EnsureValidNullability();

The expected behaviour for the above code is that an InvalidOperationException should be throw if the non-nullable-reference-types behaviour is enabled and nothing should happen if it's not.

I've created PR #40 to pull in some unit tests to help you diagnose.

I tried poking around with the code to see if I could create a PR with a possible solution but I'm afraid that I got lost! The first problem is that in "ValidateNullability" there is a call to obj.GetType() that doesn't check whether "obj" is null (which is why there is NullReferenceException regardless of whether the value should be allowed to be null or not) but I think that the "IEnumerable" handling has to take into account the type of items in the list and whether they're allowed to be null - I got stuck trying to do that; I could dig around and get the types of "T" that any given enumerable type might implement IEnumerable<T> for but I failed to correctly determine whether those "T" values should be Unknown, Nullable or NotNullable. I then had a quick look at the documentation here and got completely lost trying to track how to work out what generic type parameters should be marked as nullable or not!

Please let me know if I can include any additional information, example cases or other help.

Upgrading from 3.0.1 to 3.1.0 breaks NSwag documentation

When upgrading from Namotion.Reflection package 3.0.1 to 3.1.0, something broke when generating the documentation page using UseSwaggerUi3 with NSwag

This is my code for calling UseSwaggerUi3, pretty basic, and worked fine with Namotion.Reflection 3.0.1

app.UseSwaggerUi3(typeof(Startup).Assembly, settings => { settings.GeneratorSettings.Title = "MyApi"; });

However after updating to 3.1.0, the documentation page yields a 500 error:

image

Downgrading to 3.0.1 makes it work again.

Any settings I should change in the UseSwaggerUi3 parameters ?

I'm using .NET Framework 4.7.2 for this project.

Thanks

Loading the assembly fails with PowerShell Core 7

Whenever I try to call
Add-Type -Path "D:\Test\Namotion.Reflection.dll"
in a PowerShell session it fails with
Could not load file or assembly 'Namotion.Reflection, Version=1.0.12.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102'.

The loading of a big .NET Core Project even with Entity Framework Core succeeds. Just the Namation.Reflection assembly cannot be loaded. Do you have any ideas what the issue could be? Any special dependencies or such? Some ideas that I could try?

GetXmlDocsSummary not working for interfaces

Properties with summaries defined in interfaces do not have their values retrieved when calling GetXmlDocsSummary, either on the base class or on the interface directly.

public interface IConfigInfo
{
    /// <summary>
    /// Test Path
    /// </summary>
    string Path { get; set; }
}
public class ConfigInfo : IConfigInfo
{
    /// <inheritdoc />
    public string Path { get; set; }
}
typeof(IConfigInfo).GetMember("Path").First().GetXmlDocsSummary(); // ""
typeof(ConfigInfo).GetMember("Path").First().GetXmlDocsSummary(); // ""

EnsureValidNullability doesn't work(?)

I've tried to come up with the simplest example to test how the EnsureValidNullability extension method would work - I would expect it to throw in the following code because the "Name" property of the PersonDetails is a string and #nullable enable is specified for the file and the value in the JSON is null:

#nullable enable

using System;
using Namotion.Reflection;
using Newtonsoft.Json;

namespace Tester
{
    static class Program
    {
        static void Main()
        {
            var json = "{ \"ID\": 123, \"Name\": null }";
            var p = JsonConvert.DeserializeObject<PersonDetails>(json);
            p.EnsureValidNullability();
            Console.WriteLine("Shouldn't get here - line above should throw");
        }
    }

    public sealed class PersonDetails
    {
        public PersonDetails(int id, string name)
        {
            ID = id;
            Name = name;
        }
        public int ID { get; }
        public string Name { get; }
    }
}

I've recreated this using .NET Fiddle to try to make it as quick and easy to reproduce: dotnetfiddle.net/fmha4i

How to set custom XML docs path

Hi,

I'm trying to help with the following issue that generates documentation via NSwag in Azure Functions v2. I know what the problem is but I need to determine where NSwag get's the xml documentation from.

I think it's coming from this package.

In order to solve the issue, I need to be able to set a custom xml file path. In Azure Functions on the server, this is different then the path when you locally develop.
So I tracked the code through NSwag to this package and ended up with the method GetXmlDocsPath.

So the ultimate questions are:

  1. Is this the correct line that NSwag is using to obtain the XML file for the documentation?
  2. If so, How can I set a custom path to the XML file in NSwag and then of course here in this package?

Question: how to get .ToContextualProperty().Nullability the same for emitted properties as for a coded ones

What am I trying to do?

Generate NRT-compatible classes using Reflection.Emit

What do I expect?

An emitted class having the same attributes as a coded one provides the same Nullability values for every property

What happens

Despite of having the very same attributes on emitted class, every emitted property is having the Unknown nullability while the coded ones are having the Nullable nullability.

I don't think this is a Namotion.Reflection bug, just trying to find someone to help me finding out what am I missing =)

Repro: https://github.com/bessgeor/namotion-reflection-emit-vs-roslyn (asserts the observed behavior).

Get nullability of array element type or ContextualType of array element type

Given a field declaration such as public string?[] Array; there doesn't appear to be a way to get the nullability of the element type, as opposed to the array itself. I might have missed it, but I couldn't find anything that would let me get it anywhere.

I also need to do this for nested arrays like public string?[]?[] Array; - so I'd actually prefer an equivalent to Type.GetElementType() that returns a ContextualType for the element type, rather than just getting the nullability of the element type, as that would allow me to traverse all element types of nested arrays, including more complex elements that have generic arguments.

C# 9 Record properties XML Documentation not carrying over the the generated property description

C# 9 records are documented this way:

    /// <summary>
    /// Returns a list of items.
    /// </summary>
    /// <param name="PageNumber">The page number.</param>
    /// <param name="PageSize">The page size.</param>
    public record ListItems(int PageNumber, int PageSize);

The expectation would be that the <param> documentation would carry over into the description of the property when the schema is generated.

Documentation not being generated for models from NuGet packages

I have some models exposed in my APIs that come from NuGetPackages.

While those types are properly documented (I can see the doc in intellisense), they have no documentation in the generated OpenApi spec.

This does not happen on netcoreapp2.1, but does happen on netcoreapp3.1.

To highlight this issue, please see this repro:
3.1 branch :
https://github.com/jeremyVignelles/TestNSwagNetCoreApp/blob/repro/doc-external-models/TestNSwagNetCoreApp/Hello.cs#L42

2.1 branch:
https://github.com/jeremyVignelles/TestNSwagNetCoreApp/blob/repro/doc-external-models-netcoreapp2.1/TestNSwagNetCoreApp/Hello.cs#L42

I used a type from the NSwag NuGet package to highlight the issue.

Incorrect nullability for nested class containing an async method in the parent class

I noticed "Unknown" nullability was given for a nested class when the parent class contains an async method. The use case I have is I have an async unit test which use a nested test class for the unit tests of a factory method. The following is a minimal example of the problem, given the method "Test" in run in a nullable context, note that it works as expected if the async "Test" method is removed:

static void Main(string[] args)
{
	// Gives Nullability: NotNullable
	var data = typeof(StringData).GetProperties().First().ToContextualProperty();
	
	// Gives Nullability: Unknown
	var dataInner = typeof(Outer.StringDataInner).GetProperties().First().ToContextualProperty();
}

public class Outer
{
	public async Task Test()
	{
		await Task.Delay(1);
	}

	public class StringDataInner
	{
		public string Text { get; } = string.Empty;
	}
}

public class StringData
{
	public string Text { get; } = string.Empty;
}

`EnsureValidNullability` doesn't work with records

I'm trying to use EnsureValidNullability in my project, but it always crashes on any record with:

System.InvalidOperationException: 'Method may only be called on a Type for which Type.IsGenericParameter is true.'

Wrong cached value pulled from cache

Hello,

when getting informations for the following two methods:

void Test( int test, bool bvalue );

void Test( bool bvalue = true );

When using ToContextualParameter on the parameter of the second overload, I'll get the information from the second parameter of the first overload which is wrong.
The property information for the parameter of the second method is drawn incorrectly from the dictionary because the cache key is not selective enough to distinguish between the two overloaded methods.

ContextualFieldInfo throws with generic types

I am using NJsonSchema (11.0.0) with Namotion.Reflection (3.1.1) and encountered a problem during schema generation. Below is a shorted example of my usecase.

public class Hashid
{
    protected long _id;

    ...
}

public sealed class Hashid<T> : Hashid
    where T : EntityBase
{
    ...
}

public Request
{
    public Hashid RegionId { get; set; } // works
   
    public Hashid<Domain.Entities.User> UserId { get; set; } // fails
}

During the schema generation and exploration of the Request the following exception is thrown:

System.InvalidOperationException: This operation is only valid on generic types.
   at System.RuntimeType.GetGenericTypeDefinition()
   at Namotion.Reflection.ContextualType.<get_Fields>b__36_0(FieldInfo field)
   at System.Linq.Enumerable.SelectArrayIterator`2.Fill(ReadOnlySpan`1 source, Span`1 destination, Func`2 func)
   at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
   at Namotion.Reflection.ContextualType.get_Fields()
   at NJsonSchema.NewtonsoftJson.Generation.NewtonsoftJsonReflectionService.GenerateProperties(JsonSchema schema, ContextualType contextualType, NewtonsoftJsonSchemaGeneratorSettings settings, JsonSchemaGenerator schemaGenerator, JsonSchemaResolver schemaResolver)
...

This happens because in the Fields property of the ContextualType class the TypeInfo is generic but the DeclaringType of the field is not.

grafik

This could be related to #139.

I currently resolved this issue for me by not having the Hashid<T> inherit from Hashid and copy part of the logic.

Support Overloaded GetEnumerator

I'm trying to use JsonSchema.FromType<System.DirectoryServices.AccountManagement.UserPrincipal>()
but it's throwing an InvalidOperationException.

I suspect the reason is that ArrayList.GetEnumerator has an overload which is not working with
https://github.com/RicoSuter/Namotion.Reflection/blob/master/src/Namotion.Reflection/Context/ContextualType.cs#L146

I don't fully understand your code but I'd like to suggest the following possible solution
var getEnumeratorMethod = Methods.SingleOrDefault(m => m.Name == "GetEnumerator" && m.Parameters.Length == 0);

EnumerableItemType regression in v2?

typeof(IReadOnlyList<int>).ToContextualType().EnumerableItemType

Returns Int32 in version 1.0.23.

But in the current version 2.0.10 it returns null. (It also returns null in 2.0.0.)

XML Docs file not correctly resolved on some machines

XML Docs file not reliably resolved (depending on OS/machine).

For more information see:
RicoSuter/NSwag#3465 (comment)

The big problem here is that the xml docs dlls in nuget packages (any external nuget and also asp.net core) are not put into the output folder so we need to look them up in the nuget cache folder, etc. this is super hacky at the moment. You can find the code here:

https://github.com/RicoSuter/Namotion.Reflection/blob/master/src/Namotion.Reflection/XmlDocsExtensions.cs#L801

There are also unit tests for this here to test or debug this on different machines:
https://github.com/RicoSuter/Namotion.Reflection/blob/master/src/Namotion.Reflection.Tests/XmlDocsExtensionsTests.cs#L598
https://github.com/RicoSuter/Namotion.Reflection/blob/master/src/Namotion.Reflection.Tests/XmlDocsExtensionsTests.cs#L611

The problem is that this works on some machines/OSes and does not on other, so the output is not stable...
Any better idea how to solve this?

Resolution can be disabled with XmlDocs.ResolveFromNuGetCacheOrDotNetSdk = false;

PublishTrimmed cause XML documentation to disappear

In .NET core >= 3.0, when <PublishTrimmed>true</PublishTrimmed> and the project that uses this package is published, the following libraries get trimmed, because reflection is used:

  • System.IO.FileSystem
  • System.Xml.XPath.XDocument
  • System.Xml.Linq

Impact

XML documentation cannot be loaded by this library. This can affect NSwag, where the generated swagger.json lacks documentation for published applications with this flag enabled. This is not blocking as the application works normally, but it's a difference between the application tested in the dev environment and the application that gets pushed into production.

Workaround

You can use one of the technique described here.
For example, you could add these lines into your .csproj:

  <ItemGroup>
    <TrimmerRootAssembly Include="System.IO.FileSystem" />
    <TrimmerRootAssembly Include="System.Xml.XPath.XDocument" />
    <TrimmerRootAssembly Include="System.Xml.Linq" />
  </ItemGroup>

What are the options for Namotion.Reflection / NSwag

  • Do nothing : People that gets those issues will be redirected here after a quick google search
  • Warn users clearly in the documentation : "This package makes use of reflection, if you are using PublishTrimmed in your project, please see ..."
  • Explicitely force users to include the TrimmerRootAssembly by adding a build/<PackageName>.props into Namotion.Reflection's package, which contains the above XML inside a <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> tag.
    In N.R.csproj, add this so that it gets packed:
  <ItemGroup>
    <None Include="build\Namotion.Reflection.props" Pack="True" PackagePath="build\" />
  </ItemGroup>

Direct references to this package would then have the TrimmerRootAssembly added, and these assemblies should not get trimmed.

For indirect references (like in NJS.csproj), you can use:

<PackageReference Include="Namotion.Reflection" Version="XXX" PrivateAssets="None" />

The value of None might be overkill here, see the doc. The idea is to tell msbuild "Let properties/item groups leak into my project, and get referenced as well when someone references me"

  • Remove the use of Dynamically loaded APIs. You can do that by keeping the code between
#if NETSTANDARD1_0
// Dynamically loaded API
#else
// API is always present, and use it directly
#endif

Impacted target frameworks

Netstandard & netcoreapp that get included in a netcoreapp application.

GetXmlDocsSummary is not working for inheritance across multiple projects

The GetXmlDocsSummary method currently does not return a value for properties inherited from classes of other projects

A simple example:
Project A

public class MainTest
    {
        public static void Main() {
            foreach (PropertyInfo prop in typeof(ChildClass).GetProperties())
            {
                Console.WriteLine("Name: " + prop.Name);
                Console.WriteLine("Summary: " + prop.GetXmlDocsSummary());
            }
        }
    }

public class ChildClass : ParentClass { }

Project B

public class ParentClass
    {
        /// <summary>
        /// This summary will not be shown
        /// </summary>
        public string Value { get; set; }
    }

Output:
Name: Value
Summary:

XmlDocs for parameters may not generate correctly when param tag uses cref to methods

Consider the following usage of a param XML tag in the source code:
/// <param name="baz">Boolean returned from method <see cref="int.TryParse(string?, out int)"/>.</param>

When compiling the corresponding XML documentation file, it will generate:
<param name="baz">Boolean returned from method <see cref="M:System.Int32.TryParse(System.String,System.Int32@)"/>.</param>

When Namotion.Reflection.XmlDocsExtension processes this to get the XmlDocs for this parameter, the current logic results in the final value of:

Boolean returned from method Int32@).

The issue is with the logic in XmlDocsExtension.ToXmlDocsContent():

attribute = e.Attribute("cref");
if (attribute != null)
{
    value.Append(attribute.Value.Trim('!', ':').Trim().Split('.').Last());
}

The current code assumes there are no '.' separators after the target type or method name in the cref.

Set repo url on package info

Summary

I wish for the nuget packages to have the repository url property set correctly

Details

By providing the repo url it will make it easier to contribute and can be used by source-link.

Nullability Unknown when in reality it is known

Seeing this screenshot of the debugger for the latest .NET Core 3 preview and C# 8.0 enabled I see this:

Screen Shot 2019-07-31 at 16 39 07

As you can see there's the NullableAttribute and it has NullableFlags. It just seems to not detect those.

I'm using Namotion.Reflection 1.0.5.

ContextualType.Properties fail when type is generic but not the declaring type of a property

Had this bug while using NJsonSchema.

Repro:

        public class ParentClass
        {
            public string Property { get; set; }
        }

        public class GenericChildClass<T> : ParentClass
        {
        }

        public void Repro()
        {
            var ct = typeof(GenericChildClass<string>).ToContextualType()
            // this fails because the property's declaring type is not generic
            _ = ct.Properties;
        }

Here is the code that fails in ContextualType.cs because property.DeclaringType (ParentClass) isn't generic even if GenericChildClass<string> is. The call the GetGenericTypeDefinition() throws because ParentClass is not generic.

                if (this.TypeInfo.IsGenericType && !this.TypeInfo.ContainsGenericParameters)
                {
                  PropertyInfo runtimeProperty = property.DeclaringType.GetGenericTypeDefinition().GetRuntimeProperty(property.Name);

Incorrect results for generic value types

I'm not sure if I'm using the library wrong but as far as I can tell I appear to be getting some incorrect results.

public class MyType
{
    public (string, Uri?) MyProp { get; }
}

public static void Main(string[] args)
{
    var prop = typeof(MyType).GetProperty("MyProp").ToContextualProperty();

    Console.WriteLine(prop.Nullability);
    Console.WriteLine(prop.GenericArguments[0].Nullability);
    Console.WriteLine(prop.GenericArguments[1].Nullability);
}

I'm getting the string as Unknown and the Uri as NotNullable. This doesn't look like it's an issue if I change the tuple to Dictionary<,> though so maybe it's specific to ValueTuples?

EnumerableItemType seems not working for Dictionary

typeof(Dictionary<string, int>).ToContextualType().EnumerableItemType

returns null.

The reason seems to be that

typeof(Dictionary<string, int>).GetRuntimeMethod("GetEnumerator", Array.Empty<Type>())
    .ReturnParameter?.ToContextualParameter().Type.ToString()

returns System.Collections.Generic.Dictionary`2+Enumerator[System.String,System.Int32].

And the current implementation looks like:

var returnParam = getEnumeratorMethod.ReturnParameter?.ToContextualParameter();
if (returnParam?.GenericArguments.Length == 1)
{
_enumerableItemType = returnParam.GenericArguments[0];
return _enumerableItemType;
}

CachingXDocument.ElementByNameCache is not cleared

Hi,

in your open api middleware you clear the XmlDocs cache with XmlDocs.ClearCache but CachingXDocument.ElementByNameCache is not cached.

I also do not understand why this is even static. Could it not return values from the wrong document?

GetXmlDocsSummary is not working as expexted for generic base classes

The GetXmlDocsSummary method currently does not return a value for properties inherited from a generic class.

A simple example:

var type = Assembly.GetExecutingAssembly().GetTypes().First(x => x.Name.StartsWith("Child"));
foreach (var propertyInfo in type.GetProperties())
{
    Console.WriteLine($"{propertyInfo.Name}: {propertyInfo.GetXmlDocsSummary()}");
}

public class GenericParent<T>
{
    /// <summary>
    /// This summary will be ignored.
    /// </summary>
    public T? Value { get; set; }

    /// <summary>
    /// This summary will also be ignored.
    /// </summary>
    public string? AnotherValue { get; set; }
}

public class Child<T>: GenericParent<T>
{
    /// <summary>
    /// This summary will be shown.
    /// </summary>
    public string? Name { get; set; }
}

Output:

Name: This summary will be shown.
Value:
AnotherValue:

obj.EnsureValidNullability doesn't seem to work if obj is Dictionary<string, T>

For example

static void Main( string[] args )
        {
            var s = @"
{
    ""a"": {
        ""User"": {
            ""user_name"":""john.mancini"", ""Id"":123
        },
        ""name"":""John Mancini""
    },
    ""b"": {
        ""User"": {
            ""user_name"":""john.mancini"", ""Id"":123
        },
        ""name"":""John Mancini""
    }
}";
            var obj = JsonConvert.DeserializeObject<Dictionary<string, MyClass>>( s );
            obj.EnsureValidNullability();
        }
public class MyClass
    {
        [JsonProperty( "user" )]
        public User User { get; set; } = null!;

        [JsonProperty( "name" )]
        public string Name { get; set; } = null!;
    }

    public class User
    {
        [JsonProperty( "user_name" )]
        public string UserName { get; set; } = null!;

        [JsonProperty( "id" )]
        public int Id { get; set; }
    }

This code throws an error 'Unable to cast object of type 'System.String' to type 'test.MyClass'.'
I am not sure if it is known that there are issues related to ensuring the validations of dictionaries. If so, we can delete this issue. A similar error is thrown for Dictionary<int, T>. But T seems to have to be a custom class, or at least not int or string

Nested types can incorrectly show Unknown instead of NotNullable for properties

The following code works as expected, it outputs "PersonDetails.Name.Nullability: NotNullable" -

#nullable enable

using System;
using Namotion.Reflection;

namespace Tester
{
    static class Program
    {
        static void Main()
        {
            Console.WriteLine("PersonDetails.Name.Nullability: " + typeof(PersonDetails).GetContextualProperties()[0].Nullability);
        }

        public sealed class PersonDetails
        {
            public PersonDetails(string name) => Name = name;
            public string Name { get; }
        }
    }
}

(See dotnetfiddle.net/Jqdk7S)

However, if I add a second nested classed with Program then the output becomes "PersonDetails.Name.Nullability: Unknown" -

#nullable enable

using System;
using Namotion.Reflection;

namespace Tester
{
    static class Program
    {
        static void Main()
        {
            Console.WriteLine("PersonDetails.Name.Nullability: " + typeof(PersonDetails).GetContextualProperties()[0].Nullability);
        }

        public sealed class PersonDetails
        {
            public PersonDetails(string name) => Name = name;
            public string Name { get; }
        }

        public sealed class RoleDetails
        {
            public RoleDetails(string name) => Name = name;
            public string Name { get; }
        }
    }
}

(See dotnetfiddle.net/9rYIow)

Looking at the attributes that the compiler generates for these, it seems to remove the [NullableContext] attribute from the PersonDetails class in the second version and append it to the Program class, though it leaves the [Nullable] on PersonDetails - I've started reading through your explanations of these attributes but I don't understand enough yet to be able to tell whether this could be causing the problem!

image

image

C# 8 nullable inside array not taken into account

Disclaimer: I only tested in NSwag, but I assume that the root cause is in NJSonSchema. Since I don't know how things works here, I did not test in NJS. Feel free to move the issue if it doesn't belong here.

This is a continuation of RicoSuter/NSwag#1951

After implementing my property like this:

        [JsonProperty(Required = Required.Always)]
        [ItemsCanBeNull]
        public string[] NullableStrings { get; set; } = {"Hello", null, "World"};

It is working as I expected, but now, I'm trying to migrate my code with C#8 nullables, so I tried to do that:

        [JsonProperty(Required = Required.Always)]
        public string?[] NullableStrings { get; set; } = {"Hello", null, "World"};

But it doesn't generate the nullability information properly, while it does on a plain string? property.

Repro : https://github.com/jeremyVignelles/TestNSwagNetCoreApp/blob/repro/array-of-nullables2/TestNSwagNetCoreApp/Hello.cs#L60

Nullability not obtained for generic arguments of base type

I'm interested in observing the nullability attributes of a type like Derived in

public class MyBase<T> { }
public class Derived : MyBase<string?> { }

In this case NullableAttribute for the string? is directly placed on the Derived type.

I tried calling ToContextualMember and ToContextualType on typeof(Derived) but neither appear to expose this information - correct me if I'm wrong but it seems like this functionality isn't present in the library yet. I propose we add it and can contribute time to expedite this.

documentation in readme seems off

The doc for TryGetPropertyValue looks copy-patsed

Object extensions

HasProperty(): Determines whether the specified property name exists.
TryGetPropertyValue(): Determines whether the specified property name exists.

Extend documentation sources.

There are severals issues asociated to multiple documentation files or missed documentation files.

NSwag: 2161
Namotion.Reflection: 33

We need to provide a way to include documentation files sources or just add it to the Cache.

Nullable information seems to be confused by overloads

  • "Namotion.Reflection" Version="1.0.11"
  • netcoreapp3.1
  • dotnet 3.1.101

Code:

using System;
using System.Reflection;
using Namotion.Reflection;

namespace ReflectionTest
{
    class Program
    {
        public string? Test1(int i)
        {
            return null;
        }
        public Program Test1(double j)
        {
            return null;
        }
        public string? Test2(int i)
        {
            return null;
        }
        public Program Test2(double j)
        {
            return null;
        }

        static void PrintInfo(MethodInfo m)
        {
            var nullability = m.ReturnParameter.ToContextualParameter().Nullability;
            Console.WriteLine(m.Name + "," + m.ReturnType.Name + "," + nullability);
        }
        static void Main(string[] args)
        {
            PrintInfo(typeof(Program).GetMethod("Test1", new[] { typeof(int) }));
            PrintInfo(typeof(Program).GetMethod("Test1", new[] { typeof(double) }));
            PrintInfo(typeof(Program).GetMethod("Test2", new[] { typeof(double) }));
            PrintInfo(typeof(Program).GetMethod("Test2", new[] { typeof(int) }));
        }
    }
}

Expected output:

Test1,String,Nullable
Test1,Program,NotNullable
Test2,Program,NotNullable
Test2,String,Nullable

Actual output:

Test1,String,Nullable
Test1,Program,Nullable
Test2,Program,NotNullable
Test2,String,NotNullable

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.