Secondary project with Mediatr not working c# - c#

I wanted two separate a logic into a secondary project using mediatr. When I place the handlers into the working mediatr project, it works fine, but in the new project it says:
No service for type 'MediatR.IRequestHandler .... has been registered.
Register your handlers with the container.
The Program.cs already contains of builder.Services.AddMediatR(typeof(Program)); It contains all the nuget, the working mediatr project contains.

Related

.net6 IServiceProvider service registered in runtime loaded assembly not resolved by main assembly (application parts)

The project I'm working on has multiple DDL's loaded at runtime, with common interfaces to pass the main IServiceCollection to register custom services.
The following was working in TFM net461 and no longer works after migrating to net6.
Project structure:
Main assembly: .net core web app MVC
Side assemblies: .net core sdk ddl (application parts)
The main problem being the DbContext service, registered in Startup.ConfigureServices by calling the common interface method and passing in the main assembly IServiceCollection:
services.AddDbContext<DatabaseContext>(options => {
if (!options.IsConfigured) options.UseSqlServer(Configuration.GetConnectionString(connectionString));
});
After all the runtime registrations take place, I can successfully see the service registered in the collection in the main assembly (by debugging internal properties).
However, in Startup.Configure with the injected IServiceProvider I'm not able to find the previously registered service DatabaseContext if the code is executing in a different assembly than the one in which it was registered.
While it gets correctly resolved within the same runtime assembly where the service was added in the first place.
I tried:
Checking all of the project's dependencies to make sure the versions are correct;
Creating a scope with IApplicationBuilder.ApplicationServices.CreateScope() and using the IServiceProvider of the scope; -- same result
I'm expecting the service to be found by all executing assemblies (main and dynamically loaded ones) like it was when executing within .NET Framework with TFM net461.
It seems as if every loaded assembly has its own IServiceCollection only when executing IServiceProvider.GetService, even if every assembly its using the same instance of IServiceProvider provided by the main executing assembly (the one with the startup).
What seemed to cause the described issue was how I was loading the external assemblies.
Previously in net461 the following procedure was working:
Assembly.LoadFile(dll)
Indeed allowing by reflection to instantiate the types that implement the custom interfaces, and all the code had the same 'execution context'.
Thus allowing other assemblies (e.g. the main assembly, but also other side-assemblies) to correctly obtain the registered services.
After some research and other tries, I came upon the following docs: About AssemblyLoadContext
The main principle was about the shared depencencies section, so I tried to replace the previous line with:
AssemblyLoadContext.Default.LoadFromAssemblyPath(dll)
With this change, finally the behaviour was the same as before upgrading to net6.

Move di container into his own project in .NET Core

I'm building an API in .NET Core 3.1. I try to decouple this project in the typical 3 layers. Instead of having an UI layer, I have the API project with the controllers. I also have a class library project for the logic, and another class library project as the data access layer.
I'm trying to use dependency injection over all projects. My problem is, that I have, until now, registered my interfaces and classes as services in the ConfigureServices method in startup.cs, in my API project.
But that would mean, that the logic, and the data access layer would reference the API project. To solve this, I thought, it would be the best, if I move the DI container into his own "mapping" class library project and reference this in all other projects. Would that be a good practice?
If yes, how could such a project look like, how to setup the container and how will it be instantiated in the API's project ConfigureServices method in startup.cs?
But that would mean, that the logic, and the data access layer would
reference the API project
I don't think it should, just opposite, API project will be solution entry point, sole project which "knows" about all other dependencies and glue them together.
Other projects need to reference IServiceCollection Interface, which can be done by installing Microsoft.Extensions.DependencyInjection NuGet package.
Every project can introduce own "registration" method, which can be called by entry point.
// In Logic project
public IServiceCollection AddLogic()
{
services.AddSingleton<MyLogic>();
// Add other logic types
return services;
}
// In Data project
public IServiceCollection AddDataAccess(string connectionString)
{
services.AddTransient<IRepository, SqlRepository>();
services.AddDbContext<MyDbContext>(o => o.UseSqlServer(connectionString));
return services
}
// Startup
var connectionString = Configuration.GetConnectionString("MyDatabase");
services.AddLogic();
services.AddDataAccess(connectionString);
Only way where other projects need to reference API project is when you are using some types from API project. If this the case, then move them to the project where they are going to be used or introduce another project which both API and other project can reference.

A project can't reference another project of the same solution - the method or operation not implemented

I would like to use some of methods from my c# console app project ("EPS logic") in UWP project ("EPS view") in same solution.
I tried that to add reference- Calling methods from different Projects in one Solution.
But when I tried to I got two errors:
Cannot add reference to project "EPS Logic"
and
The method or operation is not implemented.
Additionaly I got some warnings like this about all classes from my EPS logic project:
warning DV2002: Class 'SequenceMaker' is not mapped to any Dependency Validation diagram
But I don't know if it's part of that problem. Should I not try to add anything to UWP project in first place?
You will not be able to reference a console app from a UWP project; they are not compatible! If it is really just logic, you should create a .NET Standard class library or a UWP class library and put your logic there. You should be able to reference that just fine.
If you are wanting a console app and a UWP app with shared logic, split that logic out into a .NET Standard class library, then reference that from both the console and UWP projects.

Cycles detected

My project does not add reference to another in the same solution.
I created a project for a website and and abstracted all the parts of the program into .Net Class Libraries (My models in a different class library, Interfaces in a different class library, business logic in a different class library). I referenced all the projects correctly and I also tried creating something I call EntityRepository which I initially kept the DbContext inside. But due to the reason that I wanted to use Microsofts' implementation of Identity and then scaffold the logic out, I could not find the DbContext from the other project which is required when scaffolding so I had to exclude that project out of the solution. Normally when you create a project and select Single user authentication, .Net core adds an initial DbContext into the project. So when scaffolding the implementation of AspNetCore Identity into my project, i have to choose the DbContext. Because of that, my business logic has broken into two sides. The other logic is inside another project in the same solution, the Identity and authentication is inside the startup project which is the web application. When I tried calling the services which implement the business logic from the other project into the web project, it could not add reference to the services project. I now added reference manually. After that I now saw an error written
Detail Error:
Severity Code Description Project File Line Suppression State
Error NU1108 Cycle detected.
CBTSoftware.Web.Host -> CBTSoftware.Services -> CBTSoftware.Web.Host. CBTSoftware.Web.Host C:\Users\Tavershima\source\repos\CBTSoftware\CBTSoftware.Web.Host\CBTSoftware.Web.Host.csproj 1```
How can I resolve this?
Fist I want to show gratitude to those who answered above because they put on the right track to solving this issue. In my case the issue was caused by untrack files causing NU1108 and was resolved by running git clean -fxd
*git clean documentation
I know that this is old but I'd like to add here as well.
I had the same situation as Sebastian Widz answer but what really worked for me was opening the Properties of the problematic project.
This reloaded the project files/dependencies and fixed the "Cycle Detected" issue.
In my case the problem had nothing to do with actual dependencies.
One day I opened a solution (which was fine the day before) and could not compile it. NU1108 Cycle detected error was reported in error log for several projects.
Solution:
Examine all projects in the solution, check the solution content.
If for some projects you see wrong content like if the project had files attached from a different project, expand its nodes and wait a bit, VS should refresh the nodes after a while
You may also try to Clean Solution and Reload each project.
Consider making a project to contain your EntityRepository, like CBTSoftware.Data, and adding a reference to it from your services project:
CBTSoftware.Services -> CBTSoftware.Data
Then, you can continue referencing your services project from your web project:
CBTSoftware.Web.Host -> CBTSoftware.Services
You'll still be able to configure your EntityRepository in your Startup.cs file because it will know about your CBTSoftware.Data project transitively. Just make sure to remove the reference to your web project from your services project, since this is creating a cycle.
I have solved the problem by deleting the DbContext which i created in the Web Project and using the one which I created in another project which is a .Net Library then I added this line of code in my StartUp.cs file
services.AddDbContext<CBTDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
By adding it, I was able to find the DbContext in the Web Project.
Then another problem has arisen when I'm trying to add migrations. Which I would open in another post
I also had this issue
In my case, I was using multiple projects in one solution. And in one of those projects, it's Dependencies was showing warning signs, within these Dependensies, there was a folder with included projects also each showing a warning sign.
I could solve it by right-clicking on the Dependencies, click on 'Add Project Reference' and then unselect all projects related to it/showing the warning signs.
After rebuilding, the cycle problem was gone.

WCF Method not found after signing an assembly

I have a 3 projects in a solution like such:
WCF Service: Hosts a couple of methods
Class Library: Acts as a gateway to the WCF service by returning an instance of its Soap client
WPF Application: Consumes the service methods via the referenced class library
Everything was working perfectly...the application was accessing an instance of the soap client through the library and consuming the methods accordingly.
Now I signed my assemblies and everything still compiles and when I add new methods and update the service reference in the library, the new methods come up in the application...but when running the application and try to use a method, a MissingMethodException is thrown:
Method not found:
'MusicData.Entities.User
DBAccess_Gateway.DBInteraction_Service.DBInteractionGatewayClient.User_Login(System.String,
System.String)'.
This is the line its failing at:
var user = WSGateway.MR_WebService.User_Login(username.Text, crypto.Encrypt(passphrase.Password));
I think it has something to do with the assemblies (now in the gac because they are signed?) being signed...but why arent the methods are not being found? Are the signed assemblies not being updated correctly now?
When you update the service references in your class library, make sure you are creating a new version of the assembly and registering this new version in the GAC, then make sure your WPF app is referencing this new version.

Categories

Resources