9

I am trying to get into the new ASP.NET MVC 6 stuff, but I'm having a very hard time with their new DI system. I have tried to find resources online, but everything I find covers only the absolute most bare minimum to use it.

I was previously using Ninject, and I have several wire-ups that work like this:

Bind<IDocumentStore>()
    .ToMethod(c => CreateDocumentStore())
    .InSingletonScope();

private static IDocumentStore CreateDocumentStore() {
    // lots of initialization code, etc.
    return documentStore;
}

But so far I am having a difficult time finding out how to translate this kind of behaviour to Microsoft's new DI system. All I can find are examples like this:

services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();

and:

services.AddMvc();

Where everything seems to work entirely on the default constructor for the target service. Is there any way to produce the behaviour I am needing in this new DI system?

I've seen the

services.Configure<TOptions>(options => {});

But I'm not really clear on whether that will do what I am thinking, or if it is reserved for specific behaviours.

DavidG
  • 113,891
  • 12
  • 217
  • 223
Ciel
  • 4,290
  • 8
  • 51
  • 110
  • Why are you trying to migrate from Ninject to the new DI system? That new DI system supports just a subset of what Ninject (and other containers) supports and the built-in DI system will be [unusable for any reasonably sized SOLID application](https://stackoverflow.com/questions/30681477/dependency-injection-in-the-asp-net-5-vnext/30682214#30682214). – Steven Jul 29 '15 at 09:32
  • I don't doubt that you're right, but to be honest most of your post goes over my head. I'm basically only needing constructor injection, and MAYBE property injection one time. But I will endeavor to research it a bit more – Ciel Jul 29 '15 at 10:22
  • Well, to be honest, I don't think I ever use property injection; I just use constructor injection. But once you start adding cross-cutting concerns such as logging, audit trailing, permission checks, validation, transaction management, etc, etc, you'll be happy if you have [an architecture](https://bit.ly/1vouSrm) that allows you to add cross-cutting concerns in a simple and elegant way using [decorators ](https://en.wikipedia.org/wiki/Decorator_pattern). It's simply impossible to apply decorators with the vNext container as you can do with one of the mature containers. – Steven Jul 29 '15 at 11:43

2 Answers2

7

The AddTransient method has various overloads, one of which accepts a lambda expression:

services.AddTransient<IDocumentStore>(s => CreateDocumentStore());

However it seems you are using the Ninject InSingletonScope() modifier so this may be more appropriate:

services.AddSingleton<IEmailSender>(s => CreateDocumentStore());

Additional note: There is some pre-release documentation available (of course, it's not complete and may be incorrect but may help)

DavidG
  • 113,891
  • 12
  • 217
  • 223
  • services.AddSingleton also allows a factory lambda and would be the equivalent of the Ninject registration. – Paul Hiles Jul 29 '15 at 08:51
  • @PaulHiles You could be right, I don't really know much about Ninject. I'll edit that in. – DavidG Jul 29 '15 at 08:56
  • I'm sorry, but I tried this and the method you're talking about doesn't seem to exist. – Ciel Jul 29 '15 at 23:10
  • @Ciel I've just tested it to confirm and these both work in my version. Perhaps you're running an older version? – DavidG Jul 30 '15 at 00:38
  • Yes, you were right. There was something preventing it from showing. After a scrub and a reinstall, it worked right! – Ciel Jul 30 '15 at 23:45
3

Also you could continue use Ninject by adding Microsoft.Framework.DependencyInjection.Ninject to your project and then configure it with following code:

public IServiceProvider ConfigureServices(Microsoft.Framework.DependencyInjection.IServiceCollection services)
{
    var kernel = CreateMyKernel();
    kernel.Populate(services); // Wire up configured services and Ninject kernel with Microsoft tool
    return kernel.Get<IServiceProvider>();
}
STO
  • 10,390
  • 8
  • 32
  • 32
  • Unfortunately, this method does not work anymore. They've changed the `ConfigureServices` method recently and it does not return anything. – Ciel Sep 25 '15 at 19:19
  • It doesn't work even if you try to force remove IServiceProvider? – STO Sep 28 '15 at 09:01
  • So I can just register Ninject like normal, like I did in MVC 5, and it should work fine? – Ciel Sep 28 '15 at 10:24
  • 1
    No :( Here http://stackoverflow.com/questions/32788637/continued-ninject-support-in-asp-net-mvc-6 mentioned Microsoft's Ninject adaptor was removed. But it is still available https://github.com/aspnet/DependencyInjection/tree/f0897c2b26413e9187f6d1bd245a3dce0ac9b0f8/src/Microsoft.Framework.DependencyInjection.Ninject on github. Also see here http://forums.asp.net/t/2044835.aspx?Full+examples+of+using+other+DI+containers+such+as+ninject+ – STO Sep 28 '15 at 12:15