Method Not Found when using LightInject with MVC5 and .Net 4.5 - c#

When setting up LightInject for an MVC controller I am getting an error when calling container.EnableMvc(); in the injector setup.
Error:
Method not found:
'Void LightInject.WebContainerExtensions.EnablePerWebRequestScope(LightInject.IServiceContainer)'
Source:
public static void Register() {
var container = new ServiceContainer();
container.ScopeManagerProvider = new PerLogicalCallContextScopeManagerProvider();
WebContainerExtensions.EnablePerWebRequestScope(container);
container.RegisterControllers();
container.Register<ISomeClass, SomeClass>();
container.EnableMvc();
}
Additional Information:
I am running the code locally through Visual Studio
The project is 4.5
My OS is Windows 10 (framework 4.5)
In the past when I have setup LightInject I have set the scope lifetime manually but the documentation, for general setup and MVC specific examples, has since changed. I came across one thread that mentioned this could be an issue with not including LightInject.Web as a dep, but I can see it listed as a dep for LightInject.MVC and in the list of references in the project.
Are there any other steps I can take to manually configure the lifetime or otherwise verify that this method is available before Enabling MVC?

The issue here was that I installed LightInject.MVC with NuGet. It lists it's dependencies as:
LightInject.Web (>= 1.0.0.4)
LightInject (>= 3.0.1.7)
The after I exhausted this being an issue with versions of .Net 4.5 and possible issues with async. I decided to manually update both LightInject.Web and LightInject to their newest versions. After the update it resolved the issue.
I will add this as a bug in the listed dependencies on the projects site.

Related

Base Code Issues (?) with ASP.NET Core OAuth

I'm using the ASP.NET Core Authentication.OAuth package (version 2.2.0) to develop middleware for a unique authentication flow in my web app. I am using .NET Core 3.1. I'm running into several issues where it seems that there are constructors/methods missing from the package's base code, creating missing method exceptions that I cannot resolve (for example, this exception, which I've gotten around but haven't truly resolved: "MissingMethodException: Method not found: 'Void Microsoft.AspNetCore.Authentication.OAuth.OAuth CreatingTicketContext..ctor" which I got when trying to instantiate an OnCreatingTicketContext object). I've tried uninstalling and re-installing the OAuth package, so I don't believe it's a problem with my specific installation. Although I've managed to work around some of these errors, I'm presently unable to instantiate new OAuthTokenResponse objects in my extended OAuthHandler class.
Calling OAuthTokenResponse.Success(response) produces a missing method exception ("Method not found: 'Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse.Success(Newtonsoft.Json.Linq.JObject)'"). If I try to directly specify each of the object's fields (as below), I am met with another error: "'OAuthTokenResponse' does not contain a constructor that takes 0 arguments".
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var result = new OAuthTokenResponse()
{
Response = payload,
AccessToken = payload.Value<string>("access_token"),
TokenType = payload.Value<string>("token_type"),
RefreshToken = payload.Value<string>("refresh_token"),
ExpiresIn = payload.Value<string>("expires_in")
};
Indeed, it seems from the class definition that there is no constructor defined taking any number of arguments, though I suspect that it exists and just isn't accessible, so maybe that's to be expected. Whatever the case may be, I don't know what to do and I can't tell whether it's something I'm doing wrong or it's a problem with the package itself. Any insights?
This problem sprouted from having multiple references to the same set of packages. I had not realized that ASP.NET Core versions after 2.2 were not referenced by inclusion of Nuget packages and that the .NET Core 3.1 framework supplied the most recent versions. I uninstalled/deleted references to the version 2.2 packages and the problem vanished.

MediatR setup for shared Class Library in Console vs WebAPI

I have a .Net Core 2.2 class library that uses the CQRS pattern with MediatR. I add all my dependencies into a serviceProvider in Main and attach MediatR via:
serviceCollection.AddMediatR();
var serviceProvider = serviceCollection.BuildServiceProvider();
Everything works like a charm and I am able to send any of my commands or queries to MediatR without fail.
I want to use the same exact library in a WebApi (also .Net Core 2.2) and set up my serviceProvider the exact same way inside of the Startup.ConfigureServices() method and I get the following exception when calling any controller that uses MediatR:
InvalidOperationException: Handler was not found for request of type MediatR.IRequestHandler`2[Core.Application.Accounts.Queries.GetAccountListQuery,System.Collections.Generic.List`1[Core.Application.Accounts.Models.AccountViewModel]]. Register your handlers with the container. See the samples in GitHub for examples.
MediatR.Internal.RequestHandlerBase.GetHandler(ServiceFactory factory)
I was able to resolve the issue by explicitly adding each command or query prior to adding MediatR to the DI container:
services.AddMediatR(typeof(GetAccountListQuery).GetTypeInfo().Assembly);
services.AddMediatR();
But does this mean I have to register every single IRequest object in my library? How is MediatR able to register them for me in the Console app but not in the WebAPI? Is there a better method?
I have seen this post that recommends assembly scanning, however it perplexes me that my Console app seemed to do this automatically. Also I am not sure I want to move to Autofac just yet. I have seen some packages to help you do the same with the default ServiceProvider - however I really want to avoid adding extra dependencies unless absolutely necessary.
It should be enough to just have this:
services.AddMediatR(typeof(GetAccountListQuery));
or just
services.AddMediatR(typeof(Startup));
It works for me in ASP.NET Core 2.2. The project has these two NuGet dependencies:
MediatR version 6.0.0
MediatR.Extensions.Microsoft.DependencyInjection version 6.0.1
P.S. For those, who minuses - any class from assembly would work. I used GetAccountListQuery as an example because it is for sure inside the right assembly. See my comments below.

WebApi controller tests method not found

I have a very simple WebAPI 2 controller running on .NET Framework 4.6.2, that looks like this:
[RoutePrefix("Invitations")]
public class InvitationsController : CqrsApiController
{
[HttpPost, Route("Clients/{id:long}/Actions/Cancel")]
public IHttpActionResult PostClientInvitationCancel(long id, [FromBody] ClientInvitationCancelCommand command)
{
Execute(command);
return SeeOther("Invitations/Clients/{0}", id);
}
}
and am trying to write an NUnit test for it, like this:
[TestFixture]
public class WhenExecutingAValidCommand
{
[Test]
public void ItShouldReturnARedirect()
{
var dispatcher = Substitute.For<ICqrsDispatcher>();
var urlHelper = Substitute.For<UrlHelper>();
urlHelper.Link(Arg.Any<string>(), Arg.Any<object>()).Returns("https://tempuri.org/");
var sut = new InvitationsController(dispatcher);
sut.Request = new HttpRequestMessage();
sut.Configuration = new HttpConfiguration();
sut.Url = urlHelper;
var response = sut.PostClientInvitationCancel(1, new ClientInvitationCancelCommand());
response.Should().BeOfType<SeeOtherRedirectResult>();
}
}
```
However, when I run the test, I get the following error:
System.MissingMethodException : Method not found: 'Void System.Web.Http.ApiController.set_Request(System.Net.Http.HttpRequestMessage)'.
at ApiProjectTests.InvitationsControllerTests.WhenExecutingAValidCommand.ItShouldReturnARedirect()
The same code seems to work fine in similar projects based on .NET Framework 4.5.1, so I'm wondering if there's some sort of DLL hell going on here. System.Web.Http is using Microsoft.AspNet.WebApi.Core.5.2.3, whereas System.Net.Http is coming from the GAC (well, C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll to be more precise).
Update: if I try to debug into the unit test, the error occurs before I even enter the method. So although VS2017 compiles the tests just fine, when the test runner fires up, then everything falls apart. Sounds more like DLL hell to me.
Update 2: if I comment out the setting of the request, then I can debug into the test method. If I then put in a breakpoint, and then use the Immediate window to directly set the request property, it works, and there is no Method not found error. I also disabled Resharper and used VS2017's Test Explorer to run the tests, in case R# was caching something, but it made no difference.
It looks like my problem is indeed DLL hell, more specifically the DLL hell referenced by https://github.com/dotnet/corefx/issues/25773. The issue is caused by other NuGet packages that contain references to the newer version of System.Net.Http (4.2.0.0). The current solution appears to be to add a binding redirect to downgrade the assembly version to the expected version (4.0.0.0), but so far that has not helped me.
The solution that did work for me was to install the latest NuGet package of System.Net.Http, and use assembly binding redirects in my test project to ensure that it used the 4.2.0.0 version instead of 4.0.0.0.
This is often caused by early versions of nuget packages targeting .NET standard, which have dependencies on OOB ("out-of-band") packages. OOB packages are a kind of polyfill for dlls that are part of .NET framework but not .NET standard. Here is a very good explanation of what happened. In my case, the following helped:
I identified the nuget package that had a dependency on the system.net.http 4.2.0 nuget package, and upgrade that package.
The dependency was no longer present in the upgraded package, so i could uninstall the system.net.http 4.2.0 nuget package.
The upgraded package of course still expects the reference to the system.net.http 4.0.0 assembly, so in case of doubt, you may reinstall the upgraded package to make sure that the assembly reference is in your *.csproj file.

Why WindowsIdentity class is not visible in .NET Core

Having the code below in VisualStudio 2017 .NET Core 2.0 Console App
using System;
using System.Security.Principal;
namespace smallTests
{
class Program
{
static void Main(string[] args)
{
var identity = WindowsIdentity.GetCurrent();
}
}
}
Why am I getting the error:
The name 'WindowsIdentity' does not exist in the current context
If I can see this class in .NET Core 2.0 library in .Net Core docs ?
Same code works in .NET Console app.
[EDIT]
#Will #JohnnyL Commented that I do not refer, System.Security.Principal.Windows.dll, that is true.
But I am curious why it is not working, because
in .NET 4.6.1 project (where class WindowsIdentity is visible) I also do not refer this System.Security.Principal.Windows.dll specifically. However i refer System.dll.
I always thought that it works like namespace hierarchy. For instance, when I refer to
System.Security.Principal.dll
i can use class which is in
System.Security.Principal.Windows.dll.
Am I wrong?
I added System.Security.Principal.dll to .NetCore solution by hand but it still does not work.
[EDIT2]
#Will Thank you a lot for expaining the subject it helped me a lot.
I tried to figure out is WindowsIdentity compatible with Core and it seems that it is please see:
in this apisof.net in Declarations area i can see that WindowsIdentity is in .Net Core 2.0 System.Security.Principal.Windows, Version=4.1.1.0, PublicKeyToken=b03f5f7f11d50a3a
but i do not have System.Security.Principal.Windows.dll in references, should I add it? If yes from where?
in .NET Core api reference i see this class in the list (what is the purpose of that listing if it is not compatible with core?
I also find information about that class in that link
Am I looking in wrong places?
Microsoft announced Windows Compatibility Pack for .NET Core a few weeks ago,
https://blogs.msdn.microsoft.com/dotnet/2017/11/16/announcing-the-windows-compatibility-pack-for-net-core/
And by analyzing the source code of System.Security.Principal.Windows.csproj and the commit adding it,
https://github.com/dotnet/corefx/blob/master/src/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj
My conclusion is that this is also part of the Windows only compatibility libraries, so can only be used on Windows.
To add that to your project, open your csproj and add a PackageReference tag for System.Security.Principal.Windows manually (or use Visual Studio's NuGet Package Manager).

Getting Autofac to work with MVC6/ASP.NET5

I cannot get autofac to work, I have looked at this potentially duplicate question, but it doesn't help.
I am using the full .NET stack, DNX 4.5.1
I have included the following dependencies.
"dependencies": {
// matched latest autofac version with latest dependencyinjection version.
"Autofac": "4.0.0-beta8-157",
"Autofac.Framework.DependencyInjection": "4.0.0-beta8-157",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final" ...
And the following initialisation code.
// void?
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var container = new ContainerBuilder();
...
// compilation error here!
container.Populate(services);
}
I am receiving this error:
Error CS1503 Argument 2: cannot convert
from'Microsoft.Extensions.DependencyInjection.IServiceCollection' to
'System.Collections.Generic.IEnumerable<Microsoft.Framework.DependencyInjection.ServiceDescriptor>'
MuWapp.DNX 4.5.1 C:\MuWapp\Startup.cs 54 Active
For RC1 you will need to use the Autofac.Extensions.DependencyInjection package.
https://www.nuget.org/packages/Autofac.Extensions.DependencyInjection/
We renamed our package to align with Microsoft's rename to Microsoft.Extensions.DependencyInjection. It's been a moving target supporting the early DNX releases.
As I've mentioned in the comment, you should use compatible versions of all packages in your project.json. I see on their page: https://github.com/autofac/Autofac/releases that they have released version for RC1, however there is no Autofac.Framework.DependencyInjection for RC1, so if you require this package, you will be unable to run it.
I think you should use built-in dependency injection during your development untill there is RTM version and all of the third-party packages will become stable.
Build-in DI has functionality for injecting classes into controllers, properties as well as attributes, so unless you use some advanced scenarios in which autofac is necessary, you should stick to asp.net 5 DI.

Categories