The Asp.Net landscape is changing rapidly. We have servers running on Linux, Mac and Windows. This is something that until recently is unheard of for Microsoft, and it's awesome. This also means that sometimes you need to get what you know, and learn the new way. Http Modules and Handlers for example are going away, and they're being replaced with this new fangled thing called Middleware. You might ask what is Middleware... we'll get to that.

Warning the following information may cause the following emotions :anguished: :sweat: :rage: :cry: :fearful:, they will hopefully be followed by :relaxed: :smile:

Out with the old...

Today if you want to make some portable way of modifying requests into your Asp.Net application, you would have two choices, depending on your needs. Http Modules, and Handlers, they each served a specific purpose, and were both equally useful. In Asp.Net 5, they are GONE.

  • Http Module kb

    Modules allowed you to tap into the Lifecycle of your requests, do things like add custom authentication or authorization, request redirecting, and other fun things. Mastering Http Modules made you a god among of your peers, because lets be honest they aren't always the most straight forward.

    To hook in a module you had to either use a programmatic API that was undocumented and always made me feel a little dirty (DynamicModuleUtility I'm looking at you! ::) or you added a convoluted web.config entry. Order mattered because any module that ran before you could redirect the request before you had a chance to deal with it (FormsAuthenticationModule... :imp:).

  • Http Handler kb

    Handlers allowed you to materialize something from... well memory... or the database... or some other cache. I've used them for emitting embedded resources (JavaScript, CSS, etc) or just making a dynamic response where I don't want the full weight of MVC. All in all, they're very useful.

    To hook in a handler you had to use web.config... and don't try to register the same handler twice or IIS gets really really angry. :rage4:

Now don't worry, the sky is not falling! You can still do the exact same things, just how you go about accomplishing that is different.

In with the new...

So, to recap Modules and Handlers are ~~GONE~~. You can still use them as part of an IIS deployment if you really wanted to, but Asp.Net doesn't just run in IIS, you can use Kestrel on a Mac for example.

The replacement is thing called "Middleware". Wikipedia is no help, it tells us Middleware is software that runs in the middle of something else... but that means basically everything from the kernel to drivers to the OS is a Middleware of some kind.

So what is Middleware?

Middleware is essentially a chain of callbacks, or a pipeline. The callbacks get the incoming request as input, they do there work, and then choose to continue down the pipeline or not.

If you have ever looked at NodeJS, several libraries have popularized the use of Middleware, Connect and Express. A lot of what Asp.Net 5 does, is very similar in concept to the NodeJS way.

Your callback can... * add HTTP Headers * modify the HTTP response * authenticate the user * log information about the request * anything you can imagine

Order has importance, your Middleware will run in order it was added. Your Middleware has the choice to continue, fork or stop.

  • continue will call the next Middleware that was added.
    • This is great for things like autentication, or error logging for example.
  • fork will call a different Middleware, and you can control when to follow the fork.
    • This allows you to do things like isolate a section of your application, based on the path and the user that's authenticated. *
  • stop will not call the next Middleware and the request will return.

With the ability to control absolute ordering you are not longer tide to a specific set of application lifecycle of events. You in fact get to build your own application lifecycle. You can make both good choices or bad choices, but whats important is you get to make the choice.

Why Middleware?

So you might ask, why Middleware? Why not something else entirely?

Performance Tax! You get to choose how to compose your application will the Middleware available to you. A good way to look at it is as Lego blocks (perhaps Minecraft blocks if that's your thing!). You can pick and choose how you put the blocks together to make something awesome. The Asp.net team calls this pay-for-play, you only pay for what you're using.

In addition you can stop paying for a feature you'll never use. If aren't making a social application you can remove facebook, google and microsoft authentication. If you don't need Mvc, you don't use MVC. If you don't need Razor, you don't load Razor. If all you're going to serve is lolcats, you can remove everything but the code you need to serve lolcats.

Types of Middleware

As you saw earlier, there are several different kinds of Middleware.

Terminal Middleware

The first simplest is terminal Middleware, this Middleware does not have to call through to the next caller, you can simply act on the request. Below is Hello World in Asp.Net 5.

This uses app.Run which is a terminal Middleware builder. If you change it up and try to add another app.Run call it will do nothing.

Chaining Middleware

You can then chain Middleware off of each other, to produce a combined result at the end.

Forking Middleware

Forking Middleware lets you make a decision, in this example you can choose to go one way when the condition is met. In this example I'm just using an Arbitrary random number to produce a result.

Out of the Box Middleware

Out of the box there is lots of Middleware that comes with Asp.Net 5.


In essence Middleware makes your applications pipeline explicit, which makes it easier to understand how a particular application will behave given different incoming requests. Gone are days where magic just happens, and with it, needing to understand the magic.

If you're still not quiet sure what Middleware is or how it is helpful, reach out to myself on twitter, or even touch base with the aspnet5 team via #aspnet5.

Traditionally in AspNet applications Dependency Injection was fairly hard to pull off, and even harder to pull off properly. In fact it usually felt a little like pulling teeth with a sledge hammer :hammer:. Welcome to the new world with DNX. Not only is .NET going Cross-Platform but Dependency Injection is now a first class citizen!

What is Dependency Injection?

If you've lived under a rock, or in the past you heard the words "XML Configuration" and promptly ran away :scream: (I don't blame you) then you might not know what Dependency Injection is about.

Wikipedia tells us...

In software engineering, dependency injection is a software design pattern that implements inversion of control for software libraries. Caller delegates to an external framework the control flow of discovering and importing a service or software module.

In a nut shell what it means is that instead of writing code like...

public class MyController {
    private readonly DbContext _context;
    public MyController() {
        _context = new DbContext();
    }
}

You write code like...

public class MyController {
    private readonly DbContext _context;
    public MyController(DbContext context) {
        _context = context;
    }
}

What Inversion of Control means is that your class no longer needs to understand how to construct it's dependencies. Instead the Container will hand you a list of dependencies for you to use.

At first you'll be scared :scream: or perhaps even angry :angry:. There are advantages to entering this brave new world.

  • Unit testing becomes much much easier, when you can easily stub and mock and dependencies that you are injecting.
  • Code sharing is much easier, you don't have to understand where, or how you get a DbContext you just ask the Container for one and it will serve it up for you.
  • Code is decoupled, and you no longer have to understand the inner workings of a dependency.

There are also some disadvantages to this brave new world... :disappointed:

  • Code is decoupled, so you no longer understand the inner workings of a dependency. > But you said this was a advantage? It is both a pro and a con in some circumstances. Generally it is a bigger advantage than disadvantage.
  • Potential unseen overhead during object creation.

What Dependency Injection looks like today

It looked something a little like the following[source]:

public static class Bootstrapper {
    public static void Initialise() {
        var container = BuildUnityContainer();

        DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(container));

        IDependencyResolver resolver = DependencyResolver.Current;

        IDependencyResolver newResolver = new Factories.UnityDependencyResolver(container, resolver);

        DependencyResolver.SetResolver(newResolver);
    }
    ...
}

You have to build the container, setup the static resolver using the container, and things get worse when you want inject services into an IHttpModule or IHttpHandler. Basically it's a lot of hoops. It was never really fun or intuitive. In fact it wasn't part of the original design of AspNet, so it was tacked on after AspNet was built.

What Dependency Injection looks like in DNX

If you do not already know DNX is the new execution environment, standing for ".NET Execution" or ".NET Cross Platform". It is the system that loads (or compiles) your code and hosts it.

As part of this new environment Dependency Injection is included as a first class citizen. Almost all of the internal code is constructed using a simple, no fancy pants :jeans:, lightweight :cloud: dependency injection container. This means as soon as you start to write your code you can begin to use Dependency Injection.

Configuring Services

As part of your application you are going to have to register your services. This can be achieved by adding items to the IServiceCollection.

In this brave new world :earth_americas: you "Pay-for-Play". That means that by default no services. No mvc, No routing, etc. To start using a new library, you have to specifically include those services. When consuming library services, the current convention is to use an extension method on the IServicesCollection interface.

To use Mvc you have to add the Mvc services. This applies to all sorts of other libraries as well, such as Entity Framework, etc.

public void ConfigureServices(IServiceCollection services) {
    ...
    // Add Mvc services to the collection
    services.AddMvc();
    ...
}

To add your own service to the services collection you can call various other methods on it.

public void ConfigureServices(IServiceCollection services) {
    services.AddTransient<IInterface, MyClass>();
}

This will add IInterface to the service collection.

Lifecycles

Every object has a finite lifetime. Sometimes it lives for the entire life of your application, like a static singleton. Sometimes you want a new item each and every time to work with. Other times you want the same item for an http request. Same can be done with Dependency Injection, you just have to tell the container what the intended lifetime is.

  • Singleton
    These services will be constructed once, and from that point forward any other request for this service will return the same instance. It is like the traditional static singleton instance pattern.
  • Instance
    These services are registered with a specific instance, this is the singleton pattern, but the instance is constructed ahead of time.
  • Scoped
    These services will generally be constructed once per request, such as a common database context.
  • Transient
    These services will be constructed every time they are requested. Just like calling new Service()

Factories

When configuring your services, you can also use a factory pattern to construct your dependencies. Factory methods are not the most optimal way to register services, the preferred style would to create a proper Factory Interface that Injects all the services you need to construct your instances.

public void ConfigureServices(IServiceCollection services) {
    services.AddTransient<IService>(x => new ServiceA(x.GetService<IServiceB>()));
}

Generic Types

With DNX you can register both open and closed generic types as well. This allows you to do things like the Repository Pattern. Inside AspNet5 there are examples of this being used for the new Options library.

public void ConfigureServices(IServiceCollection services) {
    services.AddTransient(typeof(IRepository<>), typeof(RepositoryImpl<>));
    services.AddTransient(typeof(IConfigureOptions<MvcOptions>), typeof(MyMvcConfiguration));
}

Special Types

There is also a class of special generic types, that will resolve intelligently for you as well. Currently the only type that works for the simple container is IEnumerable<>. This works much like the generic type resolution, but in this case it instead returns you an enumerable of all of the types that have been registered for that interface. This is useful when you may have more than one implementation of a given interface.

public class StrategyProvider {
    private readonly IEnumerable<Strategy> _strategies;
    public StrategyProvider(IEnumerable<Strategy> strategies) { _strategies; }

    public IStrategy GetStrategy(object instance) {
        return _strategies.First(x => x.IsFor(instance));
    }
}

Some other Dependency Injection containers also support injecting values of Lazy<> or Func<> but for the simple container built into DNX these are not supported out of the box. You are able to use any other container with DNX based applications, such as Autofac.

Constructor Injection

By default constructor injection is used to define what services are required for a given implementation.

public class MyService {
    public MyService(IServiceA serviceA, IServiceB serviceB, IServiceC serviceC) {
        ...
    }
}

In the above example, the container will return instances of IServiceA, IServiceB and IServiceC. There is no knowledge of the lifecycle by MyService.

Injectables

There is a different kind of method that I like to call "Injectable". These methods allow you to addon additional parameters, and those parameters will be injected by the DI container. These are special :snowflake: methods.

These special methods are designed such that you can avoid directly using IServiceProvider on the IApplicationBuilder or your middleware. To avoid the pitfalls with just using Service Location.

  • The Startup.Configure method is one such method.
    This allows you to inject services that you need to configure your pipeline.
public void Configure(IApplicationBuilder app, IServiceA serviceA) { ... }
  • Middleware is another.
    This allows you to include scoped services.
public void Configure(IApplicationBuilder app, IServiceA serviceA) {
    app.Run<IServiceA>((httpContext, serviceA) => { ... });
}
// OR
public class MyMiddleware {
    public RequestServicesContainerMiddleware(RequestDelegate next, IServiceA service) {}
    public async Task Invoke(HttpContext httpContext, IScopedService scopedService) {
        ...
    }
}

Using your own DI Container

Yes you can! In fact it super easy to use your own container or implement your own ISeviceProvider. The easiest way is to modify your Startup.ConfigureServices method to return IServiceProvider. This is the Service Provider that is attached with your application builder, and used from that point forward. An example for how Autofac does it, is below. Also in this example, you can now use Lazy<> or Func<> in your service dependencies.

public IServiceProvider ConfigureServices(IServiceCollection services) {
    ...
    var builder = new ContainerBuilder();
    builder.Populate(services);
    var container = builder.Build();
    return container.Resolve<IServiceProvider>();
}

Ripping back the curtain

Dependency Injection in DNX is around using Service Location. While service location is useful, it is generally frowned upon using it when you don't need to, instead you use something like Constructor Injection. When you use service location by itself, instead of using constructor injection, it tends to lead toward code that is harder to maintain, understand and unit test properly. With Constructor Injection and Injectables you should never have to even know that Service Location exists. If you are a library author understanding how things work, is also very helpful.

The AspNet team is using the existing IServiceProvider Interface, which offers the method GetService(Type type). Ask it for your type, and it will return an instance of that service (:warning: or null if no type is registered).

The first place you can encounter IServiceProvider is on IApplicationBuilder of your Startup class.

public void Configure(IApplicationBuilder app) {
    app.ApplicationServices.GetService(...);
}

IServiceProvider is also available on HttpContext.ApplicationServices and also for request based services as HttpContext.RequestServices. In the case of request services, this can be services that are different per-request (such as database sessions).

FIN

I hope you enjoyed your brief look at Dependency Injection with DNX, and hope you gained some valuable knowledge!

If you notice anything is wrong :interrobang:, not explained well enough, or you have additional questions, please feel free to leave a comment or reach out on Jabbr ( #AspNetvNext ) or Twitter.

The other weekend I created what soon Ncapsulate, a nuget wrapper for all things node. Then I got to thinking what about GUI? Right now there is not good GUI for the tools that Ncapsulate exposes. We integrate very well with MSBuild, but what if we have a build task that only needs to happen periodically? Maybe you have a task that automates the update process, for example it will locate and find the latest version of all the bower packages, and then run through the update process for each package, and then rerun your unit tests. Typically you wouldn't want to do this as part of the build, but it is a task that you want to be able to run, and you infact want everyone to be able to run easily.

Grunt Launcher

This is where Grunt Launcher comes into play. This is a wonderful tool, that keeps an eye on your gulpfile, gruntfile, bower dependencies and more. I am mainly going to focus on the Grunt and Gulp parts of this tool for this post, but please take a look at what else the tool offers.

After looking at the Grunt Launcher source I was able to determine that Ncapsulate should be entirely compatible with how Grunt Launcher runs the commands from the command line. Ncapsulte creates a .cmd file for each tool it supports, these include bower.cmd, grunt.cmd, gulp.cmd, etc. These are a required part of the tooling that lets Ncapsulates magic work correctly, and they mimic the behavior seen if you were to be using npm install -g. Grunt Launcher launches the command expecting that grunt or gulp will be in the %PATH% of the cmd. In addition Grunt Launcher launches from the root project directory of the project in Visual Studio.

What this leads to is that even if the command grunt is not in the %PATH%, but Ncapsulate.Grunt is installed. When Grunt Launcher goes to run the grunt command, the Ncapsulate version of Grunt will be picked up and will execute the task, as if it were in %PATH%.

Does it work?

To demonstrate this, I removed all of the npm .cmd files from my machine temporarily, rather I ziped them up and then deleted them.

npm files removed and attempt to run "grunt"

Then I installed Grunt Launcher into my Visual Studio instance, and loaded up Ncapsulate.Example to see what, if anything happens. Ncapsulate Example is the test project I used to verify most of the initial functionality of Ncapsulate, and it has bower, grunt and gulp installed as packages.

Bower

Bower Update All After loading up the project, and right-clicking on bower_components I'm presented with a new menu item.

Bower Update For each different bower component, we get an appropriate item in the context menu.

Bower Update result And the bower commands even run as expected!

Grunt

Grunt Under the grunt submenu there is a list for each grunt command

Grunt result In Ncapsulte example the grunt file just registeres an empty task, but it does run as expected.

Gulp

Gulp Exactly like Grunt we see all the commands for Gulp under there.

Gulp result The output here is exactly what we should expect from the given task.

Summary

Grunt Launcher is yet another tool that we can use to allow developers to not leave their comfort zone of the Visual Studio IDE. While also making sure that each developer does not need to install node and grunt or gulp on their local machine.

logo https://github.com/Blacklite/Ncapsulate

Ncapsulate is a NuGet wrapper for NodeJS and libraries of the Node Ecosystem. Such tools currently include Bower, Gulp, Grunt, Npm, Karma, and support is easy to add for more. Ncapsulate allows Front-end Developers to bring the Node Ecosystem into the .NET world without making your manager freak out at having to add "yet another tool" for everyone to install and work with.

Why should I use Ncapsulate over just using Node by itself?

  • My team already uses Node and Bower, should we use Ncapsulate? It depends, if you work with a small team that is fine with using Node and related libraries, then there is no reason why you would need to use Node by itself. Keep in mind Ncapsulate also has MSBuild integration so you can execute Gulp tasks, dependency install, and more directly from your Project. With minimal effort.

  • It is difficult for my team to adopt new tools that need to be installed, could we use Ncapsulate? Yes! Ncapsulate is portable and does not require any external dependency to be installed on Developer machines. Ncapsulate is also completely compatible with Nuget Package Restore.

Ncapsulate Use Cases

Take Bower for example, with bower you can install any number of client side technologies from Twitter Bootstrap, Angular and Font-Awesome. With no native way in Visual Studio to utilize bower we must use Nuget for some of these dependencies.

In the NuGet ecosystem some libraries are updated often and regularly to keep in sync with Bower releases but this is not always the case. In addition because of the nature of NuGet's content system, all of these libraries come with a bunch of assumptions in where the content get's placed or used.

Ncapsulate allows us to use Bower as we would normally operate through the command line, but instead we have nicer tight integration with MSBuild itself, remember csproj files are just MSBuild xml under the covers.

This also opens the door for using Less as part of our build process. Yes there are tools that developers can use such as Web Essentials. And I think Web Essetentials is awesome, I use it every day but the problem is the Editor can compile these things for us, but the build server cannot. If the Developer doesn't have the extension installed, or maybe the make a manual change to the css instead of the less. These are easy mistakes to make, but they can cause signifcant issues down the road for the next developer.

Want need configurable task runner? Combine Gulp or Grunt with MSBuild and you can run the advanced tasks like r.js in a NodeJs environment, and then package it all up with MSBuild and deploy to Azure!

How to use Ncapsulate?

Pretty simple, using Nuget of course!

Nuget Search Install like any other Nuget Dependendency!

Once installed you'll see some new files in your solution, these can be excluded from the solution if you have no need for them. Keep in mind the .cmd files must still be checked into your source control solution for Ncapsulate's tooling to work correctly.

The .targets are completely optional but they are Ncapsulates default integration point with the specific node tool. For Npm it will install and update your dependencies, same for Bower. For Gulp and Grunt you can link certian tasks to a specific phase of the build. You can compile your JavaScript BeforeBuild and run your Unit Tests with Karma AfterBuild.

And that's it, you're ready to get started!

 

 

 

 

 

 

Can I contribute to Ncapsulate?

Absolutely, there are many many, many tools to be implemented with Ncapsulate for anyone to use. I picked the top 4 that came to mind (my mind specificly) there are certianly a ton more, such as TSLint for linting typescript files, JSHint for linting JSFiles. These can all be done through Grunt or Gulp as well. The goal if Ncapsulate is to be the wrapper for the tools, and nothing more.