I am trying to install Ninject 3.3.2 in .NET Core, Released in May 2016. I got an error: The dependency Ninject 3.2.2 does not support framework .NETCoreApp, Version=v1.0.
Does anybody had similar problem, and is there any solution for this?
Ninject 3.3.0 was released September 26th 2017 and now targets .NET Standard 2.0 and thus also runs on .NET Core 2.0.
From the course of things (see issues/discussions on GitHub) it seems likely that some of the changes in the 4.0-beta will be reverted. I would not expected a 4.0 final shortly. Hence I would advise to go with the current version 3 release.
Just wanted to add; while both of the previous answers are correct in that ASP.Net core does provide built in dependency injection, it is NOT sufficient for more advanced scenarios. As it does not support a whole host of features that Ninject, AutoFac, Unity, or StructureMap supports.
At present, the only DI libraries that I am aware of that fully supports .net core are AutoFac and now Unity as well. It is very simple to add this in. The only thing you need to do to replace the built in DI is as follows. This example is for AutoFac but its almost identical for Unity it looks like.
First, replace the void on ConfigureServices in startup.cs with an IServiceProvider (dependency from AutoFac) like so:
public IServiceProvider ConfigureServices(IServiceCollection services)
Then create a container builder, build and resolve an IServiceProvider from ConfigureServices:
var builder = new ContainerBuilder();
builder.Populate(services);
var container = builder.Build();
return container.Resolve<IServiceProvider>();
I have a wrapper around the this second part that allows you to dynamically load and build different configurations using AutoFac modules, that I might be convinced to upload to GitHub or something if there is any interest.
Ninject does not support .NET Core. You can check it's website to be sure if there is no version that supports it.
ASP.NET Core has its own Dependency Injection container build in. See here.
Ninject does not support .Net Core, instead of this we can use dependency injection of .net core. following are the steps to implement.
Go to startup.cs at public void
ConfigureServices(IServiceCollection services)
Add services.AddTransient<Interface, Class>();
Go to the controller where you want to apply dependency injection.
Create a global private Interface _propertyName;
Pass the interface type variable to the constructor like
public Constructor(Interface name)
{
_propertyName= name;
}
Now you can access the members of the class through _propertyName.
Related
var builder = new ConfigurationBuilder().AddJsonFile(somepath);
Error message states
ConfigurationBuilder does not contain a definition for AddJSONFile.
If I look at the Dependencies/Packages folder this is shown :
Microsoft.Extensions.Configurations(6.0.1)
This appears to be a missing method in this version of that class.
Install Microsoft.Extensions.Configuration.Json nuget package.
Also I would suggest to consider Microsoft.Extensions.Hosting nuget which handles a lot of such concerns via generic hosting (and depends on the aforementioned package):
A host is an object that encapsulates an app's resources and lifetime functionality, such as:
Dependency injection (DI)
Logging
Configuration
App shutdown
IHostedService implementations
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.
In the past, I've used external config files with other DI frameworks such as Unity to define the mapping of which concrete type to provide when an interface is injected.
This was a great way to fully decouple an assembly containing concrete implementations from a released copy of an application consuming them. Allowing me to load an alternative assembly simply by editing the config.
I get the impression this is just not a feature of Microsoft.Extensions.DependencyInjection, especially looking through the code.
I guess I'd just like a second opinion to confirm this before I start using a different DI provider in my ASP.NET Core project.
MS DI is meant to be simple, to get easily started with and which can easily be used as basis for other IoC/DI Frameworks to plug-in to it.
It doesn't has any auto-registrations, assembly scanning or decorator/interception support. If you need such features you should use a 3rd party container, like Unity which you named already.
Unity already has extension point for Microsoft.Extensions.DependencyInjection, which can be found here on GitHub or on NuGet.
As documented on GitHub, all you need to do is run
Install-Package Unity.Microsoft.DependencyInjection
To install the package and then add this to your code
In the WebHostBuilder add UseUnityServiceProvider(...) method
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUnityServiceProvider() <------ Add this line
.UseStartup<Startup>()
.Build();
Add method to your Startup class
public void ConfigureContainer(IUnityContainer container)
{
// Could be used to register more types
container.RegisterType<IMyService, MyService>();
}
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.
It is possible to register dependencies manually:
services.AddTransient<IEmailService, EmailService>();
services.AddTransient<ISmsService, SmsService>();
When there are too much dependencies, it becomes difficult to register all dependencies manually.
What is the best way to implement a convention based binding in MVC 6 (beta 7)?
P.S. In previous projects I used Ninject with ninject.extensions.conventions. But I can't find a Ninject adapter for MVC 6.
No, there is no support for batch registration in the ASP.NET 5 built-in DI library. As a matter of fact, there are many features that are needed to build large SOLID applications, but are not included in the built-in DI library.
The included ASP.NET DI library is primarily meant to extend the ASP.NET system itself. For your application, you are best off using one of the mature DI libraries out there, and keep your configuration separate from the configuration that used to configure the ASP.NET system itself.
This removes the need for an adapter.
An MVC 6 adapter exists, but seeing as ASP.net 5 is still in Release candidate, it isn't yet available on NuGet so you'll need to add the ASP.NET 5 "master" branch feed from MyGet to your Visual Studio NuGet package sources.
A walkthrough to do this is available here:
http://www.martinsteel.co.uk/blog/2015/using-ninject-with-mvc6/
If it is still interesting for someone.
This is my solution of the issue with Autofac. It is required Autofac and Autofac.Extensions.DependencyInjection NuGet packages.
// At Startup:
using Autofac;
using Autofac.Extensions.DependencyInjection;
// ...
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Some middleware
services.AddMvc();
// Not-conventional "manual" bindings
services.AddSingleton<IMySpecificService, SuperService>();
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterModule(new MyConventionModule());
containerBuilder.Populate(services);
var autofacContainer = containerBuilder.Build();
return autofacContainer.Resolve<IServiceProvider>();
}
This is the convention module:
using Autofac;
using System.Reflection;
using Module = Autofac.Module;
// ...
public class MyConventionModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var assemblies = new []
{
typeof(MyConventionModule).GetTypeInfo().Assembly,
typeof(ISomeAssemblyMarker).GetTypeInfo().Assembly,
typeof(ISomeOtherAssemblyMarker).GetTypeInfo().Assembly
};
builder.RegisterAssemblyTypes(assemblies)
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
}