.Net core 3: The namespace internal does not exist in Microsoft.Extensions.Logging.Internal

こ雲淡風輕ζ 提交于 2020-12-05 05:34:45

问题


I have a .Net core 2.1 project that was using the Microsoft.Extensions.Logging.Internal namespace, specifically FormattedLogValues class.

I am now migrating to .Net core 3, I couldn't find a piece of documentation about where to FormattedLogValues was moved or what is its replacement.

Even the namespace documentation is removed

Any tips?


回答1:


I fixed the problem by updating moq to "4.13.1" and taking advantage of It.IsAnyType.

_logger.Verify(f => f.Log(
    It.IsAny<LogLevel>(),
    It.IsAny<EventId>(),
    It.IsAny<It.IsAnyType>(),
    It.IsAny<Exception>(),
    (Func<It.IsAnyType, Exception, string>) It.IsAny<object>()));



回答2:


This really depends on what you are doing with the type, but looking at the code in the github source it looks like the type still exists, but is internal - which means tht only the library itself can actually access the type, unless you've got the assembly InternalsVisibleTo("") - but we'll ignore that for now.

So the type itself in is an implementation of IReadOnlyList<KeyValuePair<string, object>> which is a bit of a weird one but means that if you are testing values going into the logger you can access then like so:

logger.State[0][0].Value

"State" here is what is defined in the library so the terminology is hopefully familiar.

If you are using Moq or equivilent, you could probably use:

_logger.Verify(f => f.Log(
    It.IsAny<LogLevel>(),
    It.IsAny<EventId>(),
    It.IsAny<IReadOnlyList<KeyValuePair<string, object>>>(),
    It.IsAny<Exception>(),
    (Func<It.IsAnyType, Exception, string>) It.IsAny<object>()));

If you want to use it in your own logger you would have to create your own class that inherits from the class:

public class MyLogValues : IReadOnlyList<KeyValuePair<string, object>> {}

Then both classes can be reduced down to the interface

Hopefully this helps, I think it depends on what exactly you are using the type for.




回答3:


As previous answers pointed out, you must use It.IsAnyType or It.IsValueType.

So setup would look like this:

mock.Setup(_ => _.Log(
  It.IsNotNull<LogLevel>(), 
  It.IsNotNull<EventId>(),
  It.IsAny<It.IsValueType>(),
  It.IsNotNull<Exception>(),
  (Func<It.IsValueType, Exception, string>)It.IsAny<object>());

Ps. DO NOT forget to cast the last parameter.

If you also need to check parameters passed to the method you must use InvocationAction:

mock.Callback(new InvocationAction((invocation) => {
  Assert.AreEqual(level, invocation.Arguments[0]);
  Assert.AreEqual(exception, invocation.Arguments[3]);
}));


来源:https://stackoverflow.com/questions/58500412/net-core-3-the-namespace-internal-does-not-exist-in-microsoft-extensions-loggi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!