0

Still exploring the new ASP.NET MVC5, now with build in DI!

No Problem so far, I can just inject my Handlers (I don't like the Term Service, since this defines to me a Platform-Neutral Interface):

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplicationInsightsTelemetry(Configuration);

        services.Configure<Model.Meta.AppSettings>(Configuration.GetSection("AppSettings"));

        services.AddSingleton(typeof(Logic.UserEndPointConfigurationHandler));
        services.AddSingleton(typeof(Logic.NetworkHandler));

        services.AddMvc();
    }

Works fine, also the strongly typed Configuration-Object "AppSettings" works perfectly fine.

Also the Injection in the Controllers works as well. But now my collaps: I seperated my DataAccess from the Handlers, and obviously I'd like to inject them as well:

public class UserEndPointConfigurationHandler
{
    private readonly DataAccess.UserEndPointAccess _access;

    public UserEndPointConfigurationHandler(DataAccess.UserEndPointAccess access)
    {
        _access = access;
    }

But bam, UserEndPointAccess can't be resolved. So it seems like even I directly request to DI an Class with a Parameterless-Constructor, I need to register that. For this case, sure I should Interface and register them, but what does that mean for internal helper classes I also inject?

According to the Docs: http://docs.asp.net/en/latest/fundamentals/dependency-injection.html#recommendations and also the examples I found, all people in the world only seem to communicate between Controllers and some Repositories. No Business-Layer and no Classes on different Abstraction-Levels in Assemblies.

Is the Microsoft DI approach something totally differnt than the good ol' Unity one, where I can really decouple as fine granular as I'd like to?

Thanks in advance.

Matthias

Edit @Nightowl: I add my answer here, since it's a bit longer. First of all, Unity does automatically create Instances, if I request a conecrete Type. This allows me to inject Types I register and Types, like Helper classes etc. I don't need to. This combination allows me to use DI everywhere.

Also in your Example I'd need to know the DataAcces in the WebGui, which is quite thight coupled. Well, I know there are solutions for this via Reflection, but I hoped Microsoft did something in this Topic, but probably that'd mean to big of a change.

Also allows Unity to store Instances or Instructions how to create them, another huge feature, which is missing at the moment.

Probably I'm just to spoiled, what refined DI-Libraries do, probably they also do to much, but at the moment the Microsoft-Implementation is just a huge downgrade according to my Information.

Matthias Müller
  • 3,336
  • 3
  • 33
  • 65

1 Answers1

1

MVC Core follows the the composition root pattern, which is where object graphs are created based off of a set of instructions to instantiate them. I think you are misinterpreting what the IServiceCollection is for. It does not store instances, it stores instructions on how to create instances. The instances aren't actually created until a constructor somewhere in the object graph requests one as a constructor parameter.

So, in short the reason why your service (which you call UserEndPointAccess) is not being instantiated when you request it is because you have not configured the IServiceCollection with instructions on how to create it.

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddApplicationInsightsTelemetry(Configuration);

    services.Configure<Model.Meta.AppSettings>(Configuration.GetSection("AppSettings"));

    services.AddSingleton(typeof(Logic.UserEndPointConfigurationHandler));
    services.AddSingleton(typeof(Logic.NetworkHandler));

    // Need a way to instantiate UserEndPointAccess via DI.
    services.AddSingleton(typeof(DataAccess.UserEndPointAccess));

    services.AddMvc();
}

So it seems like even I directly request to DI an Class with a Parameterless-Constructor, I need to register that.

If you are doing DI correctly, each service class will only have a single constructor. If you have more than one it is known as the bastard injection anti-pattern, which essentially means you are tightly coupling your class definition to other classes by adding references to them as foreign defaults.

And yes, you need to register every type you require (that is not part of MVC's default registration). It is like that in Unity as well.

Community
  • 1
  • 1
NightOwl888
  • 55,572
  • 24
  • 139
  • 212