Simple Injector - register HttpClient - asp.net-core

I have been having issues registering HttpClient in my project. How can I do this?. I injected HttpClient in multiple classes and I need to register it to work for the multiple constructors.

It will have error for using container.Register<HttpClient>(); directly when I test.
System.ArgumentException: 'For the container to be able to create HttpClient it should have only one public constructor: it has 3
I find a workaround based on using below code:
container.Register<HttpClient>(()=>new HttpClient(),Lifestyle.Scoped);
based on
Registering a type with multiple constructors and string dependency in Simple Injector
However, I advice that you use the built-in IHttpClientFactory in asp.net core:
The IHttpClientFactory can be registered by calling the services.AddHttpClient() in Startup.ConfigureServices method.
services.AddHttpClient();
https://learn.microsoft.com/nl-nl/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.0#basic-usage

Related

asp.net core dependency injection issue - AddScoped not creating a new instance

I've been using asp.net core dependency injection and I have seen an not expected behavior, at least for me. I'm adding a new service to the container like this:
services.AddScoped<IMyClass>(provider =>
{
return new MyClass(
"anyValue"
});
After that, I inject the class into another class to use it:
public class AnotherClass(IMyClass xxx){
}
The thing is that there are a couple configurations that are made on the MyClass constructor based on request information. The problem is that I've seen the MyClass constructor be executed at the application startup only. After that, the class seems to use the same instance for all calls. As I'm using Scoped service I'm expecting to have a new instance for each request, am I wrong?
Thanks.
Ok. The problem was that the class that was receiving the injection was added to the container as singleton. I just changed it to Scoped and everything worked well.
Thanks!

Ninject - Resolve instance per method call

I'm finding a solution to resolve an instance per method call.
Something like that:
public class ServiceAPI
{
public void ServiceAction()
{
//Call certain repository action
// Ex:
Kernel.Get<RepositoryA>().Insert();
}
}
public class RepositoryA
{
public void Insert(object a)
{
//Get logger per service call ?
var logger = Kernel.Get<RepositoryA>().Insert();
}
}
I wanna the logger instance created one time per service call and it will be used throughout the repository.
I try with Ninject.Extensions.NamedScope extensions but it haven't worked yet.
Can you have any way to deal with this scenario ?
It is not possible to achieve this by using a scoping mechanism. (InCallScope(), InNamedScope(...),...).
Scoping is only relevant when ninject is calling the constructor of a type.
Ninject cannot - ever - replace the instance that is already passed to an object.
If you want to do this you have to program it yourself.
Here's two design alternatives how you can achieve what you want:
instantiate an object tree per method invocation. If there's some service infrastructure like WCF or Web-API there are probably hooks which can be used to do so.
replace the object which should be instantiated per method call by a proxy. The proxy can then use Ninject to create the target for each method call and execute the method on it.
For proxying you can use tools like Castle DynamicProxy or LinFu. There's also Ninject.Extensions.Interception which may also be helpful.

Application_Start equivalent in ASP.NET 5

I've come across two methods on the Startup class, ConfigureServices and Configure. Is there an equivalent to the Application_Start method from previous versions of asp.net for doing arbitrary work when the application is starting?
Edit
As a follow up, what are the possible methods that ASP.NET 5 is expecting on the Startup class?
As Simple Man said, there is no direct equivalent method in ASP.NET 5; similar functionality should be started by your services when appropriate in keeping with the Single Responsibility Principle. (The closest is the Configure method, which is where you should probably "start" any services that need to be "started".) However, there is one other method often overlooked in the Startup class: the constructor. Some logic, such as loading config files, may be appropriate there.
You can see how the methods are located on the Startup class in the Hosting repository. Only the two methods you mentioned and the Startup constructor are used.
If I am not wrong from what I understood, there is no such equal method. Rather, there are two different methods, ConfigureService and Configure.
ConfigureService is a method to configure services for your project. The purpose of this method is to set dependency injection for your project. This is the method that will be fired first after constructor has been called.
Configure is a method to configure request pipeline. This method will execute after ConfigureService.
You can refer below two links :
Asp.Net 5 Startup
Asp.Net 5 Startup 2
For your last question, I did not found any other method documentation or declaration in Startup.cs class anywhere online.
You could use IHostedService interface on .NET Core 2.0 .
The IHostedService background task execution is coordinated with the lifetime of the application.When you register your class, you could do whatever you want on starting-stopping phases of application like using Application_Start and Application_End.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHostedService, MyBackgroundStartupTask>();
}
There is another option available since .NET Core 2.1. An abstract base class we could derive from, named BackgroundService

RoleProvider injection with Ninject

First off I want to say there is a ton of answers on SO and google searches surrounding this, however I'm running into an issue that prevents those solutions from working. The answer here seems to be the way to go. (kernel.Inject(Roles.Provider);)
The issue that I'm having is that when I'm trying to inject the RoleProvider Roles.Provider is null, however my custom provider is found in the list within Roles.Providers. I am thinking that Ninject is trying to access the role provider too soon.
In my NinjectWebCommon class it appears that it's using WebActivator to start itself. [assembly: WebActivator.PreApplicationStartMethod(typeof(Admin.App_Start.NinjectWebCommon), "Start")]
It appears that all of the articles I've come across are using older versions of Ninject and are doing a lot of the heavy lifting in the Global.asax Application_Start... Using my implementation how can I get DI working for a custom role provider?
I'm using the [Inject] attribute within my custom provider.
The WebActivator pipeline runs way before even the standard ASP.NET stack is created. It means that you won't have access to anything created by ASP.NET during bootstrap in NinjectWebCommon.
Use that file only to declare bindings that do not depend on ASP.NET stuff to be up.
In order to get around this issue, you should use Global.asax Application_Start handler to load any additional modules/bindings that are dependend on ASP.NET stuff such as Roles.Provider.
Here is a suggestion that may solve your problem:
public void Application_Start()
{
var kernel = (new Bootstrapper()).Kernel;
kernel.Inject(Roles.Provider);
//Other initialization stuff
}
The Bootstrapper class is a lazy singleton that has a static IKernel initialized within your NinjectWebCommon.cs. So this is the proper way of retrieving the configured kernel instance from outside your NinjectWebCommon.
Give it a try.

Using structuremap in a webesrvice, how to register the types?

I have a WCF service and need to register my interfaces and my classes with structuremap, in a regular asp.net application I would do it in global.cs in onApplicationstartup since this is called before anything else, but where do I initialize my structuremap in a webservice?
You have multiple options:
Put your Structuremap code in a static variable that is initialized on first access
Use a custom ServiceHostFactory which initializes the library before creating a ServiceHost.
Create a custom WCF ServiceBehavior which does the initialization, and apply that to all relevant services inside the ServiceLibrary.