The Evolution of .NET Dependency Resolution

Introduction

Dependency Resolution (RS), Dependency Injection (DI) and Inversion of Control (IoC) are hot topics nowadays. Basically all frameworks are aware of it, or offer some mechanisms to help implement it. It all started a long time ago, however, and things are slightly confusing at the moment – but will get better!

In this post, I won’t go through all of the details of all dependency resolution libraries in existence, instead I will only focus on Microsoft libraries. Also, I will only talk about generic dependency resolution, leaving out more specialized usages, such as WCF, WF and SharePoint, which also use similar concepts.

Origins

It all started with the venerable IServiceProvider interface. It basically provided a single method, GetService, that gave answer to “get me an implementation for this type”. That was it, the single parameter was a Type, and the response, a single object. There were no public implementations of it, but Windows Forms designers – auto generated code – used it a lot to request services from the design surfaces (aka, Visual Studio designer). You were free to implement it in any way, the only recommendation was to return null in case no service could be found, instead of throwing an exception.

ASP.NET MVC

ASP.NET MVC started as a built-in template option in Visual Studio but then migrated to NuGet deployment, which is how Microsoft now delivers its fast-moving libraries. MVC 4 introduced its own dependency injection container and API. It was built around IDependencyResolver interface, which did not implement IServiceProvider. although it offered a GetService method that had exactly the same signature – and requirements – as IServiceProvider’s. It also added another method, GetServices, for retrieving all implementations of a given service, again identified by its Type.

This time we had a registration point, which was DependencyResolver.Current. You could set it to your custom implementation, or use the default, which didn’t really return anything.

ASP.NET Web API

Web API came out a bit later than MVC, and, while sharing its philosophy, and also being delivered through NuGet, offered its own APIs, namely, for dependency injection. There was also a IDependencyResolver interface, again, not inheriting from IServiceProvider, but with a slightly more complex inheritance: now we had also IDependencyScope, which was where the GetService and GetServices methods were declared, as well as IDisposable, supposedly so that we could have dependency resolution scopes. The well-known registration point was GlobalConfiguration.Configuration.DependencyResolver.

ASP.NET SignalR

SignalR was something of an outsider in the ASP.NET stack. Like MVC and Web API, it was offered (and still is, for that matter) as a separate NuGet package. No wonder that it also offered its own dependency resolution API, in the form of IDependencyResolver. Again, not related to IServiceProvider, and as such offered a couple of other methods: besides the classic GetService (same signature and contract), we also had GetServices, and even a registration method (RegisterType with a couple of overloads). It was also IDisposable, perhaps to control registration scopes. The registration point was available as GlobalHost.DependencyResolver and there was a default implementation, appropriately named DefaultDependencyResolver.

Entity Framework 6

Leaving ASP.NET land for a moment, Entity Framework 6 also introduced its own (of course…) API for dependency resolution. The IDbDependencyResolver also offered the now classic GetService and GetServices methods, but this time, these also took an optional key parameter. GetService should not throw if a matching service was not found, and GetServices should return an empty enumeration likewise. The registration was done through DbConfiguration.DependencyResolver, no public default implementation. EF 6 expected a number of services to be supplied through dependency resolution, otherwise, it would use its own built-in defaults.

Entity Framework 7

Although still in pre-release, EF 7 shuffles things a bit. For once, the DbContext constructor can now take an instance of IServiceProvider. More details coming soon, I guess, but apparently it seems to be going back to the roots.

Unity

Unity is part of Microsoft’s Enterprise Library and long time readers of my blog should know that it’s what I normally use for inversion of control (IoC), dependency injection (DI) and aspect-oriented programming (AOP). Being an IoC container, it includes its own API, IUnityContainer, which also offered service resolution methods, besides lots of other stuff; this time, the names are Resolve and ResolveAll, with several overloads and generic as well as non-generic versions. Resolve can take an optional key, but a major difference is that the default implementation (UnityContainer) will throw an exception if a service is not found.

Common Service Locator

Because there are lots of dependency resolution libraries out there, offering conceptually similar services but with different APIs, Microsoft sponsored an open-source library for defining a common interface for dependency resolution to which interested parties could comply, or, better, write an adapter for. The code is available in Codeplex and NuGet and several library authors provided adapters for the Common Service Locator, such as Unity, Castle Windsor, Spring.NET, StructureMap, Autofac, MEF, LinFu, Ninject, etc. See a list of NuGet packages matching Common Service Locator here. The Common Service Locator API only prescribes two families of methods in its IServiceLocator API: GetInstance and GetAllInstances. Interestingly, IServiceLocator inherits from IServiceProvider, and it also features an optional key for GetInstance, like EF6 and Unity, as this is the more general case – multiple registrations for the same type under different keys, the default key is null.

ASP.NET 5

ASP.NET 5 is just around the corner, and Microsoft seems to me to be moving in the right direction. MVC, Web API and SignalR are merged together, so the dependency resolution mechanisms should be the same. The IServicesCollection (sorry, no public API documentation) interface allows for the registration and the resolution of services through the conventional Startup.ConfigureServices method and is made available in the HttpContext and IApplicationBuilder implementations as the ApplicationServices and RequestServices properties, of type IServiceProvider. Not that you typically need it, but the default implementation of IServicesCollection is ServicesCollection, and one key difference is that you do not have a global entrypoint to it, you can only access it through the current HttpContext reference, in most cases.

Conclusion

That’s it. Looking forward for your feedback on this.

Persisting SignalR Connections Across Page Reloads

I recently had the need to keep a SignalR connection even if the page would reload. As far as I know, this cannot be done out of the box, either with hubs or persistent connections. I looked it up, but could find no solid solution, so here is my solution!

First, we need to create a “session id” that is to be stored at the browser side. Mind you, this is not an ASP.NET session, nor a SignalR connection id, it’s something that uniquely identifies a session. To maintain sessions we normally use cookies, but my solution uses instead HTML5 session storage. I had to generate a session id, and there were several solutions available, from pseudo-GUIDs, to the SignalR connection id, but I ultimately decided to use the timestamp; here is it:

function getSessionId()

{

    var sessionId = window.sessionStorage.sessionId;

    

    if (!sessionId)

    {

        sessionId = window.sessionStorage.sessionId = Date.now();

    }

    

    return sessionId;

}

As you can see, this function first checks to see if the session id was created, by inspecting the sessionStorage object, and, if not, sets it.

Next, we need to have SignalR pass this session id on every request to the server. For that, I used $.connection.hub.qs, the query string parameters object:

$.connection.hub.qs = { SessionId: getSessionId() };

$.connection.hub.start().done(function ()

{

    //connection started

});

Moving on to the server-side, I used a static collection to store, for each session id, each SignalR connection id associated with it – one for each page request. The reasoning is, each page reload generates a new SignalR connection id, but the session id is always kept:

public sealed class NotificationHub : Hub

{

    internal const string SessionId = "SessionId";

 

    public static readonly ConcurrentDictionary<string, HashSet<string>> sessions = new ConcurrentDictionary<string, HashSet<string>>();

 

    public static IEnumerable<string> GetAllConnectionIds(string connectionId)

    {

        foreach (var session in sessions)

        {

            if (session.Value.Contains(connectionId) == true)

            {

                return session.Value;

            }

        }

 

        return Enumerable.Empty<string>();

    }

 

    public override Task OnReconnected()

    {

        this.EnsureGroups();

 

        return base.OnReconnected();

    }

 

    public override Task OnConnected()

    {

        this.EnsureGroups();

 

        return base.OnConnected();

    }

 

    private void EnsureGroups()

    {

        var connectionIds = null as HashSet<string>;

        var sessionId = this.Context.QueryString[SessionId];

        var connectionId = this.Context.ConnectionId;

 

        if (sessions.TryGetValue(sessionId, out connectionIds) == false)

        {

            connectionIds = sessions[sessionId] = new HashSet<string>();

        }

 

        connectionIds.Add(connectionId);

    }

}

As you can see, both on OnConnected as in OnReconnected, I add the current connection id to the collection (ConcurrentDictionary<TKey, TValue> to allow multiple concurrent accesses) indexed by the session id that I sent in the SignalR query string. Then, I have a method that looks in the collection for all connection id entries that are siblings of a given connection id. If more than one exists, it means that the page has reloaded, otherwise, there will be a one-to-one match between connection ids and session ids.

The final step is to broadcast a message to all the sibling connection ids – a waste of time because only one is still possibly active, but since we have no way of knowing, it has to be this way:

[HttpGet]

[Route("notify/{connectionId}/{message}")]

public IHttpActionResult Notify(string connectionId, string message)

{

    var context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();

    var connectionIds = NotificationHub.GetAllConnectionIds(connectionId).ToList();

 

    context.Clients.Clients(connectionIds).MessageReceived(message);

 

    return this.Ok();

}

This Web API action method will get the context for our hub (NotificationHub), look up all of the sibling connection ids for the passed one, and then broadcast a message to all clients identified by these connection ids. It’s a way to send messages from outside of a page into a hub’s clients

Problems with this approach:

  • All tabs will get the same session id, but that also happens with cookies;
  • Although unlikely, it may be possible for two clients to get the same session id, which I implemented as the current timestamp; an easy fix would be, for example, to use a pseudo-GUID, the server-side session id, or even the SignalR connection id;
  • If the page reloads several times, there will be several connection id entries for the same session id – which will be kept throughout all reloads; no easy way to get around this, except possibly using some cache with expiration mechanism.

And that’s it. Enjoy!

Hosting HTTP Resources

Introduction

How do I host thee? Let me count the ways!

You may not have realized that .NET offers a lot of alternatives when it comes to hosting an HTTP server, that is, without resorting to IIS, IIS Express or the now gone Visual Studio Web Development Server (aka, Cassini, rest in peace); by that, I either mean:

  • Opening up a TCP port and listening for HTTP requests, or a subset of them;
  • Running ASP.NET pages without a server.

In this post I am going through some of them. Some are specific to web services, but since they understand REST, I think they qualify as well as generic HTTP hosting mechanisms.

.NET HttpListener

Let’s start with HttpListener. This is included in .NET since version 2 and offers a decent server for static contents, that is, it cannot run any dynamic contents, like ASP.NET handlers, nor does it know anything about them. You merely point it to a physical folder on your file system, and it will happily serve any contents located inside it. Let’s see an example:

using (var listener = new System.Net.HttpListener())

{

    var url = "http://*:2000/";

    listener.Prefixes.Add(url);

    listener.Start();

 

    var ctx = listener.GetContext();

 

    var message = "Hello, World!";

 

    ctx.Response.StatusCode = (Int32) HttpStatusCode.OK;

    ctx.Response.ContentType = "text/plain";

    ctx.Response.ContentLength64 = message.Length;

 

    using (var writer = new StreamWriter(ctx.Response.OutputStream))

    {

        writer.Write(message);

    }

 

    Console.ReadLine();

}

This is a very basic example that just listens on port 2000, for any host name and request, and just returns Hello, World! when contacted before shutting down.

ASP.NET ApplicationHost

Complementary to HttpListener, we have a way to execute ASP.NET handlers (ASPX pages, ASHX generic handlers and ASMX web services) in a self-hosted application domain. For that, we use the ApplicationHost class to create the ASP.NET application domain, and a regular .NET class for the server implementation. An example:

public class Host : MarshalByRefObject

{

    public void ProcessPage(String page, String query, TextWriter writer)

    {

        var worker = new SimpleWorkerRequest(page, query, writer);

        HttpRuntime.ProcessRequest(worker);

    }

}

 

//strip out bin\debug, so as to find the base path where web files are located

var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location).Replace(@"\bin\Debug", String.Empty);

 

//we need to copy the assembly to the base path

File.Copy(Assembly.GetExecutingAssembly().Location, Path.Combine(path, "bin", Assembly.GetExecutingAssembly().CodeBase.Split('/').Last()), true);

 

var host = System.Web.Hosting.ApplicationHost.CreateApplicationHost(typeof(Host), "/", path) as Host;

host.ProcessPage("Default.aspx", null);

Notice the File.Copy call; this is necessary because the assembly referenced by the Default.aspx page needs to be located in the same folder as the page. An alternative to this would be to add a post build-event to the Visual Studio project:

image

I leave as an exercise to the interested readers how we can combine this with HttpListener! Winking smile

OWIN WebApp

Moving on to more recent technologies, we now have OWIN. In case you’ve been living in another world and haven’t heard of OWIN, I’ll just say that it is a standard for decoupling .NET from any particular web servers, like IIS or IIS Express. It also happens to have a self-hosting implementation – which, by the way, uses HttpListener underneath.

We need to add a reference to the Microsoft.Owin.SelfHost NuGet package:

image

After that, we just register an instance of WebApp with the default parameters, add an handler, and we’re done:

class Program

{

    public static void Configuration(IAppBuilder app)

    {

        app.Use(new Func<AppFunc, AppFunc>(next => (async ctx =>

        {

            using (var writer = new StreamWriter(ctx["owin.ResponseBody"] as Stream))

            {

                await writer.WriteAsync("Hello, World!");

            }

        })));

    }

 

    static void Main(String[] args)

    {

        using (WebApp.Start<Program>("http://*:2000"))

        {

            Console.ReadLine();

        }

    }

}

Again, no fancy dynamic stuff, just plain and simple HTTP: it waits for a request and just returns Hello, World!. It is possible to run ASP.NET MVC on top of OWIN, that is the goal of project Helios, which is currently in alpha stage. Do check out the Helios NuGet package at https://www.nuget.org/packages/Microsoft.Owin.Host.IIS/1.0.0-alpha1:

image

WCF ServiceHost

Since its release, WCF offers a way for it to be self-hosted in a .NET process. The class responsible for that is ServiceHost, or one of its descendants, like WebServiceHost, more suitable for REST. I will show an example using REST, which can be easily tested using a web browser:

[ServiceContract]

public interface IRest

{

    [WebGet(ResponseFormat = WebMessageFormat.Json)]

    [OperationContract]

    String Index();

}

 

public class Rest : IRest

{

    public String Index()

    {

        return "Hello, World!";

    }

}

 

using (var host = new WebServiceHost(typeof(Rest)))

{

    var url = new Uri(@"http://localhost:2000");

    var binding = new WebHttpBinding();

 

    host.AddServiceEndpoint(typeof(IRest), binding, url);

    host.Open();

 

    Console.ReadLine();

}

This example listens for a request of /Index on port 2000 and upon receiving it, returns Hello, World! in JSON format – because we are only sending a string, it will be wrapped in . WCF REST out of the box only supports returning data in XML or JSON format, no Text or HTML, but, to be fair, that’s not what it was meant to. Should be possible to return HTML, but, honestly, it would probably mean more work than it’s worth.

Web API HttpServer

Another web services technology in the .NET stack is Web API. Web API uses a concept similar to MVC, with controllers, models and action methods, but no views. It can be self-hosted as well, using the HttpServer class. In order to use it, install the Microsoft.AspNet.WebApi.SelfHost NuGet package. You will notice that its description claims that it is legacy, and has been replaced for another based on OWIN, yet, it is fully functional, if you don’t required it to be OWIN-compliant:

image

Because of the Web API architecture, we need to implement a controller for handling requests, :

public class DummyController : ApiController

{

    [HttpGet]

    public IHttpActionResult Index()

    {

        return this.Content(HttpStatusCode.OK, "Hello, World!");

    }

}

In this example, we do not take any parameters and just return the usual response.

Here’s the infrastructure code:

var url = "http://localhost:2000";

var config = new HttpSelfHostConfiguration(url);

config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}");

 

using (var server = new HttpSelfHostServer(config))

{

    server.OpenAsync().Wait();

}

The DummyController is found by reflecting the current executing assembly and applying conventions; any HTTP requests for /api/Dummy/Index will land there and the outcome will be plain text.

IIS Hostable Web Core

Now, this one is tricky. IIS, from version 7, allows hosting its core engine in-process, that is, from inside another application; this is called IIS Hostable Web Core (HWC). We can supply our own Web.config and ApplicationHost.config files and specify a root folder from which IIS will serve our web resources, including any dynamic contents that IIS can serve (ASPX pages, ASHX handlers, ASMX and WCF web services, etc). Yes, I know, this contradicts my introduction, where I claimed that this post would be about hosting web resources without IIS… still, I think this is important to know, because it can be fully controlled through code.

You need to make sure HWC is installed… one option is using PowerShell’s Install-WindowsFeature cmdlet:

Or the Server Manager application:

 

Features page

 

Because HWC is controlled through an unmanaged DLL, we have to import its public API control functions and call it with .NET code. Here’s an example:

public class Host : IDisposable

{

    private static readonly String FrameworkDirectory = RuntimeEnvironment.GetRuntimeDirectory();

    private static readonly String RootWebConfigPath = Environment.ExpandEnvironmentVariables(Path.Combine(FrameworkDirectory, @"Config\Web.config"));

 

    public Host(String physicalPath, Int32 port)

    {

        this.ApplicationHostConfigurationPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName() + ".config");

        this.PhysicalPath = physicalPath;

        this.Port = port;

 

        var applicationHostConfigurationContent = File.ReadAllText("ApplicationHost.config");

        var text = String.Format(applicationHostConfigurationContent, this.PhysicalPath, this.Port);

 

        File.WriteAllText(this.ApplicationHostConfigurationPath, text);

    }

 

    ~Host()

    {

        this.Dispose(false);

    }

 

    public String ApplicationHostConfigurationPath

    {

        get;

        private set;

    }

 

    public Int32 Port

    {

        get;

        private set;

    }

 

    public String PhysicalPath

    {

        get;

        private set;

    }

 

    public void Dispose()

    {

        this.Dispose(true);

        GC.SuppressFinalize(this);

    }

 

    protected virtual void Dispose(Boolean disposing)

    {

        this.Stop();

    }

 

    public void Start()

    {

        if (IisHostableWebCoreEngine.IsActivated == false)

        {

            IisHostableWebCoreEngine.Activate(this.ApplicationHostConfigurationPath, RootWebConfigPath, Guid.NewGuid().ToString());

        }

    }

 

    public void Stop()

    {

        if (IisHostableWebCoreEngine.IsActivated == true)

        {

            IisHostableWebCoreEngine.Shutdown(false);

 

            this.PhysicalPath = String.Empty;

            this.Port = 0;

 

            File.Delete(this.ApplicationHostConfigurationPath);

 

            this.ApplicationHostConfigurationPath = String.Empty;

        }

    }

 

    private static class IisHostableWebCoreEngine

    {

        private delegate Int32 FnWebCoreActivate([In, MarshalAs(UnmanagedType.LPWStr)] String appHostConfig, [In, MarshalAs(UnmanagedType.LPWStr)] String rootWebConfig, [In, MarshalAs(UnmanagedType.LPWStr)] String instanceName);

        private delegate Int32 FnWebCoreShutdown(Boolean immediate);

 

        private const String HostableWebCorePath = @"%WinDir%\System32\InetSrv\HWebCore.dll";

        private static readonly IntPtr HostableWebCoreLibrary = LoadLibrary(Environment.ExpandEnvironmentVariables(HostableWebCorePath));

 

        private static readonly IntPtr WebCoreActivateAddress = GetProcAddress(HostableWebCoreLibrary, "WebCoreActivate");

        private static readonly FnWebCoreActivate WebCoreActivate = Marshal.GetDelegateForFunctionPointer(WebCoreActivateAddress, typeof(FnWebCoreActivate)) as FnWebCoreActivate;

 

        private static readonly IntPtr WebCoreShutdownAddress = GetProcAddress(HostableWebCoreLibrary, "WebCoreShutdown");

        private static readonly FnWebCoreShutdown WebCoreShutdown = Marshal.GetDelegateForFunctionPointer(WebCoreShutdownAddress, typeof(FnWebCoreShutdown)) as FnWebCoreShutdown;

 

        internal static Boolean IsActivated

        {

            get;

            private set;

        }

 

        internal static void Activate(String appHostConfig, String rootWebConfig, String instanceName)

        {

            var result = WebCoreActivate(appHostConfig, rootWebConfig, instanceName);

 

            if (result != 0)

            {

                Marshal.ThrowExceptionForHR(result);

            }

 

            IsActivated = true;

        }

 

        internal static void Shutdown(Boolean immediate)

        {

            if (IsActivated == true)

            {

                WebCoreShutdown(immediate);

                IsActivated = false;

            }

        }

 

        [DllImport("Kernel32.dll")]

        private static extern IntPtr LoadLibrary(String dllname);

 

        [DllImport("Kernel32.dll")]

        private static extern IntPtr GetProcAddress(IntPtr hModule, String procname);

    }

}

In order for this to work, we need to have an ApplicationHost.config file, a minimum working example being:

<?xml version="1.0" encoding="UTF-8" ?>

<configuration>

    <configSections>

        <sectionGroup name="system.applicationHost">

            <section name="applicationPools" />

            <section name="sites" />

        </sectionGroup>

 

        <sectionGroup name="system.webServer">

            <section name="globalModules" />

            <section name="modules" />

            <section name="handlers" />

            <section name="staticContent" />

            <section name="serverRuntime" />

            <sectionGroup name="security">

                <section name="access"/>

                <sectionGroup name="authentication">

                    <section name="anonymousAuthentication" />

                    <section name="windowsAuthentication" />

                    <section name="basicAuthentication" />

                </sectionGroup>

                <section name="authorization" />

                <section name="requestFiltering" />

                <section name="applicationDependencies" />

                <section name="ipSecurity" />

            </sectionGroup>

            <section name="asp" />

            <section name="caching" />

            <section name="cgi" />

            <section name="defaultDocument" />

            <section name="directoryBrowse" />

            <section name="httpErrors" />

            <section name="httpLogging" />

            <section name="httpProtocol" />

            <section name="httpRedirect" />

            <section name="httpTracing" />

            <section name="isapiFilters" allowDefinition="MachineToApplication" />

            <section name="odbcLogging" />

        </sectionGroup>

    </configSections>

 

    <system.applicationHost>

        <applicationPools>

            <add name="AppPool" managedPipelineMode="Integrated" managedRuntimeVersion="v4.0" autoStart="true" />

        </applicationPools>

 

        <sites>

            <site name="MySite" id="1">

                <bindings>

                    <binding protocol="http" bindingInformation="*:{1}:localhost" />

                </bindings>

                <application path="/" applicationPool="AppPool" >

                    <virtualDirectory path="/" physicalPath="{0}" />

                </application>

            </site>

        </sites>

    </system.applicationHost>

 

    <system.webServer>

        <globalModules>

            <add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />

            <add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />

            <add name="ManagedEngine" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" />

        </globalModules>

 

        <modules>

            <add name="StaticFileModule" />

            <add name="AnonymousAuthenticationModule" />

            <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" preCondition="managedHandler" />

            <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />

            <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" preCondition="managedHandler" />

            <add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" preCondition="managedHandler" />

        </modules>

 

        <handlers accessPolicy="Read, Script">

            <add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode" />

            <add name="StaticFile" path="*" verb="*" modules="StaticFileModule" resourceType="Either" requireAccess="Read" />

        </handlers>

 

        <staticContent>

            <mimeMap fileExtension=".html" mimeType="text/html" />

            <mimeMap fileExtension=".jpg" mimeType="image/jpeg" />

            <mimeMap fileExtension=".gif" mimeType="image/gif" />

            <mimeMap fileExtension=".png" mimeType="image/png" />

        </staticContent>

    </system.webServer>

</configuration>

And all we need to start hosting pages on the port and physical path specified by ApplicationHost.config is:

using (var host = new Host(path, port))

{

    host.Start();

 

    Console.ReadLine();

}

A couple of notes:

  • Because it calls unmanaged functions, can be terrible to debug;
  • The ApplicationHost.config needs to be in the application’s binary build directory and must have two placeholders, {0} and {1}, for the physical path and HTTP port, respectively;
  • It refers to .NET 4.0, if you want to change it, you will to change a number of modules and paths;
  • Only very few modules are loaded, if you want, get a full file from %HOMEPATH%\Documents\IISExpress\config\ApplicationHost.config and adapt it to your likings.

.NET TcpListener

And finally, one for the low-level guys. The TcpListener class allows the opening of TCP/IP ports and the handling of requests coming through them. It doesn’t know anything about the HTTP protocol, of course, so, if we want to leverage it, we need to implement it ourselves. Here’s a very, very, basic example:

var listener = System.Net.Sockets.TcpListener.Create(2000);

listener.Start();

 

using (var client = listener.AcceptTcpClient())

{

    using (var reader = new StreamReader(client.GetStream()))

    using (var writer = new StreamWriter(client.GetStream()))

    {

        var request = reader.ReadLine();

 

        writer.WriteLine("HTTP/1.1 200 OK");

        writer.WriteLine("Content-type: text/plain");

        writer.WriteLine();

        writer.WriteLine("Hello, World!");

        writer.Flush();

    }

}

 

listener.Stop();

Here we’re just reading any string content and responding with some HTTP headers plus the usual response. Of course, HTTP is quite complex, so I wouldn’t recommend you try to implement it yourself.

Conclusion

I presented a couple of solutions for hosting web resources, servicing HTTP requests or running ASP.NET handlers. Hopefully you will find one that matches your needs.

Learning Microsoft Azure Review

Introduction

I was recently asked by Packt Publishing to do a review of their title Learning Microsoft Azure, and so I did.

It wasn’t the first time I did a review on an Azure book, I also reviewed Microsoft Azure Development Cookbook, Second Edition, and you can see my review here.

This time, it is an introductory book, where the reader is introduced to Microsoft Azure, and guided as he/she develops a full solution for an imaginary industrial bakery, from end to end, including a mobile app. It covers technologies such as ASP.NET MVC 5, Windows Phone 8, Entity Framework Code First and Web API, always using C# and .NET as the backing framework. At the end of each chapter, there’s a questions and answers page where we can assess our level of understanding of the topics that were discussed in it.

The author is Geoff Webber-Cross (@webbercross), which also authored another book on Azure and Windows Phone.

Chapter 1: Getting Started with Microsoft Azure

The first chapter, as we might expect, does an introduction to cloud computing and the Microsoft Azure service, presents a decision framework for aiding in selecting a cloud service as opposed to on-premises, guides the reader in creating an Azure account including it’s many services and costs, and lists the most relevant terms that we will be encountering throughout the book.

Chapter 2: Designing a System for Microsoft Azure

Here we are presented with the sample scenario, its objectives and requirements and the architectural vision of it. Different views on the system and its subsystems are presented and for each the technical decisions are explained.

Chapter 3: Starting to Develop with Microsoft Azure

Next we setup the development environment, choose a Visual Studio edition, download the required SDK and create a project to be published in our Azure account. Visual Studio Online is also presented and it’s integration with Azure, namely, in order to ensure continuous integration and delivery.

Chapter 4: Creating and Managing a Windows Azure SQL Server Database

Here we get an overview of the SQL functionality of Azure, how to create and manage databases using the portal, Visual Studio and the SQL Server Management Studio, then we learn how to use Entity Framework Code First to access and manipulate its data, and to migrate to and from different versions using the Migrations API.

Chapter 5: Building Azure MVC Websites

This chapter explains how we can build an MVC application using OAuth authentication (social accounts such as Twitter, Facebook, Google and Microsoft Live). It goes on explaining how we can set up custom domains and SSL certificates for HTTPS and how to integrate the Azure Active Directory for single sign-on and custom permissions.

Chapter 6: Azure Website Diagnostics and Debugging

This one is about diagnosing problems and debugging our applications. It presents the basic built-in tracing and logging features of Azure and how we can obtain this information and goes on to show how we can use table storage and blobs for custom storing of structured logs and its querying. Kudu is briefly introduced and at the end we learn how to do remote debugging.

Chapter 7: Azure Service Bus Topic Integration

Next up is Service Bus, Azure’s enterprise service bus service. We learn how to configure it, create and manage topics using the portal and how to use the service from our MVC application and expose it as a service.

Chapter 8: Building Worker Roles

The next chapter is about Worker Roles, a feature of Azure Websites that performs disconnected (non web-related) tasks. The reader is guided in creating a Worker Role with Visual Studio, executing it in the Emulator and publishing it to Azure. The example presented builds on the Service Bus topics discussed in the previous chapter. We also learn about other scheduling mechanism of Azure, Scheduler jobs, and implement an example using Queues.

Chapter 9: Cloud Service Diagnostics, Debugging, and Configuration

Here we learn about configuring and using the diagnostics features of Cloud Services, again expanding the concepts introduced in chapter 6. We talk about IntelliTrace and Remote Debugging and on how to connect to our virtual machines with Remote Desktop. Finally we are given an example on how to use script tasks to automate common needs.

Chapter 10: Web API and Client Integration

This chapter introduces ASP.NET Web API, Microsoft’s latest technology for building REST web services and SignalR, for asynchronous, duplex, real-time communication between web clients and the server. The provided example shows how to integrate these two technologies to broadcast messages to connected clients, including a desktop Windows Presentation Framework (WPF) application. In the end we learn how to use the Active Directory to authorize accesses to our services.

Chapter 11: Integrating a Mobile Application Using Mobile Services

Coming closer to the end, this chapter walks the reader on the various aspects of building a mobile client that connects to the cloud using Azure Mobile Services. We see how to implement a mobile-enabled web application and Web API service, how to publish it and how to implement a matching Windows Phone application, fully featured with push notifications. It also guides us on configuring the mobile service with Active Directory for authentication. At the end we are shown how to build a Windows Store app to interact with our application.

Chapter 12: Preparing an Azure System for Production

The final chapter puts everything in place, explains how to setup different build configurations for different deployment environments and how to build and deliver deployment packages for Azure. At the very end we get a deployment checklist that may come in handy if ever we run into problems.

Conclusion

Overall, I enjoyed reading this book. It doesn’t cover all of Azure, but it does a very decent job in explaining how one can build a real-life application that works and handles most typical concerns, including support for mobile devices.