Structuremap and ASP.NET core - c#

I am using ASP.NET core and I'm trying to make use of structuremap for my IoC, but I seem to be having some issues. When I write a unit test that inits structuremap directly, everything works fine. When I print the configuration out to file, I can see that my setup is indeed registering everything correctly.
However, the populate seems to be giving me trouble.
I am trying to use StructureMap.Microsoft.DependencyInjection but I get an error when I build:
The dependency structuremap >= 4.4.0 could not be resolved.
I have StructureMap 4.4.1 installed in my project, including the project I installed the StructureMap.Microsoft.DependencyInjection library into (my Web API project).
So, I then took the files out of the project on github and loaded them into my solution, and removed the nuget package, but for some reason it is not working.
Here is a plunker with the relevant files
Ideally, I'd rather use the nuget package to do this, but I've never encountered a dependency issue when I have the actual dependency already installed.
EDIT: A few more details
When I write the results of container.WhatDoIHave() to a file, my classes are all shown correctly t0 be part of structuremap, however when I run container.AssertConfigurationIsValid(); is when I am getting errors about things correctly defined as reported by WhatDoIHave()
Here is what my configure method looks like
public IServiceProvider ConfigureIoC(IServiceCollection services)
{
var container = new Container();
container.Configure(config =>
{
// scan the webapi to register all the controllers
config.Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});
//this is an IoC configuration in another library that
// ties together a bunch of class libraries so they
// don't all have to be in my web project
IoC.BootStrapper.Configure(config, "MembershipReboot");
});
System.IO.File.WriteAllText(#"C:\users\{me}\documents\structuremapTest.txt", container.WhatDoIHave());
container.AssertConfigurationIsValid();
//Populate the container using the service collection
container.Populate(services);
return container.GetInstance<IServiceProvider>();
}

Rename the "StructureMap" package to "structuremap", seems like some weird issue with NuGet casing.
Cheers :)

See this issue on the StructureMap.Microsoft.DependencyInjection issue tracker:
The dependency structuremap >= 4.3.0 could not be resolved
https://github.com/structuremap/StructureMap.Microsoft.DependencyInjection/issues/17

Related

.NET 6, Web API - configuration driven DI and NuGet package registration

I'm using .NET 6 Web API and would like to introduce some custom mocking NuGet package to our dev/test environments. I don't want this package/code to be present in further stages, so would like to do some DI registration in the appsettings.json instead of Program.cs. Would be nice to load NuGet package containing mock code as well from the appsettings.json. This would give the control of the environment via its configuration file. Is there a way to do this?
Regarding DI registration, you should be able to put part of configuration into configuration file. How exactly can it be done depends on the DI container. E.g. here is the doc for Autofac: https://autofac.readthedocs.io/en/latest/configuration/xml.html
But I don't think you can or should do similar trick for NuGet packages.

How to add a function of ConfigureService of Startup to old version MVC project

I have a problem about my project and I found possible solution in a .NET Core blog. But, unfortunately, my project is using ASP.NET MVC 5. I don't know where should I put this code to.
The code is below
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(HtmlEncoder.Create(allowedRanges: new[] { UnicodeRanges.BasicLatin,
UnicodeRanges.Latin1Supplement, UnicodeRanges.LatinExtendedA }));
}
IServiceCollection is a type used to collect service registrations. You don’t by default have IServiceCollection in ASP.NET MVC 5 like ASP.NET Core does. (You could install via nuget packages)
You could add / register HtmlEncoder to your DI container builder. If you don’t have one, take a look at example below see how to setup one for your app.
https://www.c-sharpcorner.com/article/dependency-injection-in-asp-net-mvc-5/

EF Core 1.1 to WebApi Core - Add-Migration fails

I think I’ve got all my dependencies running 1.1 properly but when I try to follow the steps here https://learn.microsoft.com/en-us/ef/core/get-started/aspnetcore/new-db I get an error running the Add-Migration command.
PM> Add-Migration InitialState
An error occurred while calling method ‘ConfigureServices’ on startup class ‘Startup’.
Consider using IDbContextFactory to override the initialization of the
DbContext at design-time. Error: This method could not find a user
secret ID because the application’s entry assembly is not set. Try
using the “.AddUserSecrets(Assembly assembly)” method instead. No
parameterless constructor was found on ‘ApplicationDbContext’. Either
add a parameterless constructor to ‘ApplicationDbContext’ or add an
implementation of ‘IDbContextFactory’ in the same assembly as
‘ApplicationDbContext’.
relevant sections of my project.json:
…
“Microsoft.EntityFrameworkCore”: “1.1.0”,
“Microsoft.EntityFrameworkCore.SqlServer”: “1.1.0”,
“Microsoft.EntityFrameworkCore.Design”: {
“type “: “build”,
“version”: “1.1.0”
},
“Microsoft.EntityFrameworkCore.Tools”: “1.1.0-preview4-final”
},
“tools”: {
“Microsoft.EntityFrameworkCore.Tools.DotNet”: “1.1.0-preview4-final”
},
My ApplicationDbContext does have the constructor:
public ApplicationDbContext(DbContextOptions options) : base(options)
{ }
and my Startup.cs does have the:
services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString(“DefaultConnection”)));
What else can it be?
The issue is related to the builder.AddUserSecrets() call. To fix perform the following steps:
Adding the user secret to the assembly (instead of just project.json) by adding attribute [assembly: UserSecretsId("aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed")] to Startup.cs
In Startup.cs replace builder.AddUserSecrets() with builder.AddUserSecrets<Startup>();
Reference: InvalidOperationException: Could not find 'UserSecretsIdAttribute' on assembly
An alternate solution:
I ran into the same problem and landed here. But I am writing an app from scratch comparing it at every step with the DotNetCore WebApp with Individual auth. that gets generated via wizard in VS 2017 hoping to follow latest practices. So it was strange when everything was identical in my code and the generated code and I was getting this exception. The generated code did not have Michael Dennis's suggested code in startup.cs, which does not mean he is wrong, it just means there was now a different way. Upon diving down further I found out that UserSecretsId was declared in myprojetname.csproj like follows:
<PropertyGroup>
<UserSecretsId>aspnet-mywebproect-006a401f-2fdc-4aad-abb1-12c00000004a</UserSecretsId>
</PropertyGroup>
After adding the entry in my project.csproj file, the issue was resolved.
Your issue is not related to EF Core, it's about User Secrets
Check your Startup.cs constructor - it contains AddUserSecrets() call. You can remove it. Later, when you read about User Secrets, you can add it back with correct configuration (I guess you have website template from 1.0.0, while referencing library 1.1.0 - it contains this bug fix)

Can't find method app.UseStaticFiles()

I'm following this guide and in step 4, I'm asked to add three lines to the project.json file (which I did and then ran dotnet restore getting a lot of updated packages).
When I enter the three lines in the Configure method, I get red lines on all of them. The methods aren't recognized, no intellisense provided etc.
I also noticed that in the example in the guide, the method signature only takes one parameter of IApplicationBuilder, whereas the one I got generated (using the yo aspnet command) looks like this.
Configure(IApplicationBuilder, IHostingEnvironment, ILoggerFactory);
I'm not sure how to resolve it. My guess is that there's a new version of something in the process (Yo, Generators, Core etc.) but I'm not entirely sure.
I've also found this blog where the method signature resembles the one I'm getting. However, the author of it suggest the same syntax that doesn't work for me. I'm guessing it's a matter of referencing the wrong libraries. How do I approach the issue?
For Asp.Net core MVC you need to install Nuget package
install-package "Microsoft.AspNetCore.StaticFiles"
That guide is outdated. The updated .Net core does not use project.json anymore which is unfortunate. Instead it is now part of csproj file. And to add the Static file library you have to add it to the project using nuget packet manager. And when you rebuild you will see an entry in csproj file for that library. I think the project.json was a great idea which was inline with core opt-in methodology, since it would allow intellisense to kick in to help you select from available libraries. And since csproj file cant be directly edited in solution you lose that feature.
Judging from the screenshots in the linked tutorial, its about ASP.NET Core RC1 (back then called ASP.NET 5 r1-final). You can easily recognize this on the package and namespace names. Microsoft.AspNet.* is used until rc1.
Starting with RC2 the packages were renamed to Microsoft.AspNetCore.* to make it clearer its a new framework and not that much compatible with legacy ASP.NET.
The UseIISPlatformHandler() isn't there anymore, it's now UseIISIntegration() within the Main(...) method:
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
And the packages the package is Microsoft.AspNetCore.Server.IISIntegration": "1.0.0" and "Microsoft.AspNetCore.Server.Kestrel": "1.0.1". For static files it's: "Microsoft.AspNetCore.StaticFiles": "1.0.0".
For the Configure overload: Configure(IApplicationBuilder); is default one, but you can add any other type which is registered with the dependency injection system (in ConfigureServices method), as it's a convention system (the startup.cs).

Ninject & WebAPI: Getting started after install from NuGet

I installed the NuGet package Ninject Integration for WebApi2 via the Package Manager Console.
According to the wiki on the project's GitHub pages, this should have created a class called NinjectWebCommon in the App_Start folder. But it didn't.
That same GitHub wiki page explains what you should see so that you can add it yourself. So I tried creating the NinjectWebCommon class myself. The problem here is that I can't find the namespace for OnePerRequestModule in the following snippet.
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
The alternative, and according to that GitHub wiki page there's no effective difference between the two, is to modify the global.asax. So I tried this method and added some bindings like so
private void RegisterServices(IKernel kernel)
{
kernel.Bind<IEntityAccess>().To<EntityAccess>();
kernel.Bind<IDictionaryRepository>().To<DictionaryRepository>();
}
and found that my project builds, but when a request is sent to the WebAPI project it can't be found (i.e., I receive a 404 response).
So there's obviously some other piece of necessary wiring up which isn't in my project.
It appears that despite changing my global.asax to derive from NinjectHttpApplication, the global.asax is no longer being called.
Can anyone tell me what I might be missing? I've uninstalled and reinstalled the NuGet package a few times but the NinjectWebCommon class never appears, nor does my global.asax file ever get modified.
I've also read Ninject's own documentation but frustratingly this is a fairly large tutorial covering the basics of IoC and how Ninject operates rather than telling you how to get started with using Ninject.
There's also this SO post asking how to get started with Ninject for WebAPI, so it looks like something's amiss with their NuGet package.
And like that, I've just found the answer: there is an additional NuGet package which must be referenced:
Ninject.Web.WebApi.WebHost
Installing "Ninject integration for WebApi2" package is not sufficient.
This really should be more clearly explained.

Categories

Resources