C
C#2y ago
sneezey

❔ Weird Type comparison always false

The same Type of ILogger<> and a type provided by ParameterInfo aren't matching despite them being the same type. Even IsAssignableTo/From aren't working either. Is there something I'm missing?
21 Replies
sneezey
sneezeyOP2y ago
parameterType: Microsoft.Extensions.Logging.ILogger`1[TCategoryName]
loggerType: Microsoft.Extensions.Logging.ILogger`1[TCategoryName]
==: False
IsAssignableTo: False
IsAssignableFrom: False
parameterType: Microsoft.Extensions.Logging.ILogger`1[TCategoryName]
loggerType: Microsoft.Extensions.Logging.ILogger`1[TCategoryName]
==: False
IsAssignableTo: False
IsAssignableFrom: False
output ^ essentially, i'm trying to discover which parameterType has an ILogger interface so I can subsitute it from ILoggerFactory
Omnissiah
Omnissiah2y ago
why aren't you checking with ILogger<Something> in the end that's what you are gonna use
sneezey
sneezeyOP2y ago
because it's generic - I want "dynamic" loading of a logger type depending on the class I'm instantiating with Activator.CreateInstance although, I've discovered they're using different paths for the Microsoft.Extensions.Logging.Abstractions.dll despite being the same version - must be something csproj related with references
Cracker
Cracker2y ago
It prints out like types are same but its determined by CLR and can be different even output says the same when you print
sneezey
sneezeyOP2y ago
parameterType: /config/workspace/<project>/src/plugins/<project>/bin/Debug/net7.0/Microsoft.Extensions.Logging.Abstractions.dll
loggerType: /config/workspace/<project>/src/apps/<different project>/bin/Debug/net7.0/Microsoft.Extensions.Logging.Abstractions.dll
parameterType: /config/workspace/<project>/src/plugins/<project>/bin/Debug/net7.0/Microsoft.Extensions.Logging.Abstractions.dll
loggerType: /config/workspace/<project>/src/apps/<different project>/bin/Debug/net7.0/Microsoft.Extensions.Logging.Abstractions.dll
Cracker
Cracker2y ago
Can you try typeA.Equals(typeB) ? it checks underlying system type which should be more accurate
sneezey
sneezeyOP2y ago
those dirs printed above were from (type).Module.FullyQualifiedName which is why they're not assignable I do utilise
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
in the csproj of <project> though
Cracker
Cracker2y ago
you might want to use Type.UnderlyingSystemType for generic types (GetGenericTypeDefinition is fine though) it ignores the generic part
sneezey
sneezeyOP2y ago
ooh, hadn't considered that will give that a whirl still nope - again, i think it's because it's loading the ILogger for its local Logging.Abstractions dll in one project, and the other project is also using it's own
Cracker
Cracker2y ago
Cracker
Cracker2y ago
there are some extensions might be useful
sneezey
sneezeyOP2y ago
find interfaces also will not be the same as the modules are different that's the core issue
Cracker
Cracker2y ago
well yes if you compare two Types named same but referenced from different assemblies, types will be different
sneezey
sneezeyOP2y ago
oh I see - won't the Type of the interface be different though?
Cracker
Cracker2y ago
parameterTypes are like ILogger<Something> right ? If ILogger is Microsoft.Extensions.Logging.ILogger and both reference are from the same dll then equality check sohuld be true with use of GetGenericTypeDefinition
sneezey
sneezeyOP2y ago
they don't again, the type.Modules are different, therefore the equality match is false i've tried with GetGenericTypeDefinition
Cracker
Cracker2y ago
you can use another project named like Project.Common and use that reference in both. That way module will be same or you can check the name equality
sneezey
sneezeyOP2y ago
nah that won't work either essentially i have:
namespace Project.One;
public class Foo : IFoo
{
public Foo(ILogger<Foo> logger){ ... }
}
namespace Project.One;
public class Foo : IFoo
{
public Foo(ILogger<Foo> logger){ ... }
}
namespace Project.Two;
class Bar
{
public Bar(Type ifoo, IServiceProvider serviceProvider)
{
var factory = serviceProvider.GetService<ILoggerFactory>();
var logger = factory.CreateLogger(ifoo);

var hasLogger = ifoo.GetConstructors().Single().GetParameters();

if (hasLogger)
Activator.CreateInstance(ifoo, new object[]{ logger });
}
else
{
Activator.CreateInstance(ifoo, null);
}
}
}
namespace Project.Two;
class Bar
{
public Bar(Type ifoo, IServiceProvider serviceProvider)
{
var factory = serviceProvider.GetService<ILoggerFactory>();
var logger = factory.CreateLogger(ifoo);

var hasLogger = ifoo.GetConstructors().Single().GetParameters();

if (hasLogger)
Activator.CreateInstance(ifoo, new object[]{ logger });
}
else
{
Activator.CreateInstance(ifoo, null);
}
}
}
the aim being Bar will create Foo if the Foo wants an ILogger Now I don't want Foo to have access to the service provider, but a "vetted" subset of items that I want it allowed access to such as the ILogger
Cracker
Cracker2y ago
Where does Foo can access the IServiceProvider if it doesnt have constructor accepts that parameter. Event if it has consturctor that take else than ILogger, it will be passed null If you have control over both project, you can use factory like FooProvider, BarProvider and manage instantiation in there rather than controling Types and Reflection
sneezey
sneezeyOP2y ago
Unfortunately I don't - I have access 5o Project.Two, but not One 😔 But fair enough - I'll keep trying This was fixed by changing
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
to
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0">
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0">
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server