Thursday, November 19, 2015

IoC Battle Thoughts...

IoC Comparisons

A co-worker sent me an article, IoC Battle in 2015..., comparing the speed differences between several IoC containers. It's a topic that comes up every once in a while. This usually happens when developers are debating which container is best. I'm a big fan of dependency injection, so I was interested to see the results.

I Ran It And Then...

I saw the results, and forked the linked repository. My first run of the benchmark app produced results similar to the article:



I dug into the code, wanting to see what was up with Windsor. The registration code was really funky. Each component was registered in a separate registration call. Regular users of Windsor know this isn't the right way to do this.

The old registrations looked like this;

After I updated them, they looked like this (I'm just showing the singleton registrations):

I reran the benchmark and got these results. The most stunning was the transient registration times. They were roughly 10% of the first run. I didn't spend much time on this. It would be interesting to see if things could be optimized further.



My Thoughts

It's important to use something correctly when doing benchmarks.

Different containers run at different speeds. The resolutions were for 1 million "web services" each which had fairly deep object graphs. So, yeah, it took Windsor some 30 seconds to do this. But then, it's unlikely a single app will be doing that. When you hit that performance demand, it's time to start scaling horizontally (more on that some other time).

In a Nutshell

Donald Knuth is quoted as having written, "The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming." If you're at the point you're worried about how fast resolving 1M object graphs is, then it's a problem. Until then, use the container that works for you.

I put my fork of this project on GitHub.

Monday, October 26, 2015

GitHub: Error: Permission denied (publickey)

With a new computer came the need to setup posh-git again. I try to use the SSH connections were possible. This time, I hit an issue. git pull in posh-git returned an error (below), but the GitHub app was working normally.


Using git bash, I checked to see if I could connect to GitHub. The results showed me that posh-git was using the default RSA key file name, id_rsa.


The fix was pretty easy: I just needed to add an entry in my ssh config file. This file is usually located in c:\Users\<your name>\.ssh. After adding the entry, I needed to restart the ssh agent. After that, everything worked fine.






Thursday, October 1, 2015

Documenting Your Code

These are my thoughts about Dennis Doomen's post on documenting code...

I dislike comments in code. They represent a failure on the author's part to express an idea in the language they're using (C#, Java, etc.). That doesn't mean I never use them, or find them completely useless. They should be the exception not the norm.

I use the class, method, and parameter names to infer what the code will do. If I have questions using an API, I try to write some form of test which captures what I want to do. If I want to know more about the implementation details, I'll go look. I think well named components and a suite of tests do a lot more to document code. They also don't go stale. I'll also favor writing tests around my code to demonstrate how it works or what it does.

When I need to see how a library works, I'll look for code examples. The online docs, and available online resources are my resources. It's rare I'll simply use the comments on the public/protected members.

Inline comments are a real red flag to me. Way too often I see them when a dev hasn't expressed themselves well enough in the language they're using. These should be really, really, really rare. The nice thing about these being so rare is they stand out. Most of the devs I've worked with have learned that an inline comment is a danger sign that we've left for one another. They also tend to disappear as a code base matures.

Commit messages are stupid important. I don't know if I consider this documenting the code. It's more a history of what happened and why it happened. It's helpful if the commit messages focus on what the changes did: "Added login screen," or, "updated main landing screen to show user name."

There's my $.02.

Thursday, August 13, 2015

Nancy Authentication with Owin and JWT

A huge part of this stuff is based upon blog posts by Jonathan Channon and Mike Hadlow.

It took me a bit of time to figure out all the working bits to building something atop Nancy using JWT for authentication. I decided to create an example app that could be used as a reference when I need to do this again. This isn't a tutorial. It's the descriptions of all the different moving parts.

The app has a very basic SPA, some RESTful endpoints, and basic unit tests. This particular app is setup for ASP.NET hosting (handy for hosting it in Azure).

The example app is on GitHub.

Solution Layout

The solution consists of two projects: NancyAspNetOwin.WebApp and NancyAspNetOwin.WebApp.UnitTests. The App directory contains all the files which comprise the SPA front-end. The Authentication directory houses the C# classes which support the token authentication. It also includes the Nancy Module which provides the endpoints that support authentication. Content, fonts, and Scripts all hold the plumbing bits such as Bootstrapper, KnockoutJS, etc. MyBootstrapper.cs and Startup.cs wire up the Nancy and Owin bits. index.html and IndexModule.cs are the kick off point.



Setting Things Up

There are a boat load of NuGet packages which need to be added when starting from an empty web application project. Some are the Nancy/Owin related stuff for the back-end. Others support the front-end SPA stuff. For this app, there were a few other things I dropped.

Nancy/Owin NuGet Packages:
  • JWT
  • Microsoft.Owin
  • Microsoft.Owin.Host.SystemWeb
  • Nancy
  • Nancy.Hosting.Aspnet
  • Nancy.Owin
  • OWIN
  • Owin.StatelessAuth
SPA NuGet Packages:
  • Bootstrap CSS
  • KnockoutJS
  • RequireJS
  • Require.JS.Text
Other Bits:
  • login.css - Pulled from bootsnip.com.
  • form.css

The web.config file needs to be updated. The system.web and system.webServer sections need things for Nancy. An appSettings entry is created for the OWIN middleware.

You'll also want to set the project to use HTTPS.
The Workflow

The flow for this app is pretty simple. A login form is displayed when first landing on the home page. When the credentials are entered, a token is retrieved from the login endpoint. This token is then used to pull the greeting from the secure endpoint.


Startup Code

There are two files running the show here: Startup.cs and MyBootstrapper.cs. Startup.cs has the Owin stuff. The pathsToIgnore variable contains all the routes we want exempted from the token-based security. These paths, along with an instance of the SecureTokenValidator class are passed into the RequiresStatelessAuth() method.



MyBootstrapper has two overrides. The RequestStartup() override contains the glue for the Owin stuff. The ConfigureConventions() override tells Nancy about the other directories that hold static content (JavaScript files, CSS files, etc.).


The Client UI

The UI implementation starts with the index.html file. Its layout was pulled from a template site. The rest of the client app is housed within the App folder. It contains the two knockout components, the config for RequireJS (config.js), and the basic application view model (myapp.js).


The index.html and myapp.js files act as the main view/view model for the app. index.html contains the markup, CSS file references, and script file references. myapp.js has the data bindings used by the app.

Each component is split into three files. These three files contain the HTML which serves as the view, the JavaScript view model, and code to register the component in Knockout.

The login component view (login-control.html) is a basic html file.


The login component view model (login-control.js) is a little more interesting. The params are come from a data binding on the index.html page. If a token is returned the page adds the token to future headers, raises an event, and hides the form. This is the spot you could store the token in a cookie or something.


The login component registration (login-control-register.js) tells Knockout what files to use to display the component. Pay attention to the template property. The use of "text!" lets RequireJS know that the file isn't a code file.


The Service Stuff

Nancy supports a number of view engines, routing definitions, etc. The NancyModule is quite capable of returning views, exposing RESTful endpoints, etc. Each module can support different authentication requirements.

IndexModule.cs is a NancyModule with two endpoints: /, and ./health. Both require an https call. /health requires that the caller supply a valid token in the request header. The RequiresAuthentication() method uses the ClaimsPrincipal data created by the SecureTokenValidator class.


The SecureTokenValidator class (lifted from here) verifies that the token provided in a request is valid. It also converts the token into the ClaimsPrincipal object used by Nancy. It's interesting to note that I've seen two variations on this class. Both have noted that the token does not directly decode to a set of claims.



Testing Notes

Nancy was designed to be very testable. There's the Nancy.Testing package goes a long way to helping with that. The Nancy documentation does a good job of explaining how to test your Nancy app. Testing Nancy with OWIN is a little more involved. You'll need the Microsoft.Owin.Testing package. OwinTests.cs in the test project gives an example of how those tests are done.

In Closing

That's all I have so far. Hopefully, this will help some other people who are trying to work through these issues.

Thursday, July 9, 2015

SPA Notes

This is an outline of some stuff for weaving KnockoutJS, RequireJS, and Bootstrap into a site. I'm not saying these are best practices or anything. Just my notes on what I have been doing. Mostly geared towards SPAs.

The Setup (Config) File


Notice that the JavaScript files do not have the .js extension in the config file. The shim property is used to ensure certain load orders (Bootstrap requires jQuery). The paths can be combined when loading dependencies.

The HTML File


It still needs the css files. The data-main attribute in the scripts tag tells RequireJS to get everything from that file.

Modules



It's not necessary to have a parameter for each dependency. The above module uses a bootstrap modal function, but doesn't need a variable (lines 34 and 55).

Examples of getting and posting some json are at lines 24 and 48. I use the $.ajax at 48, because it lets me specify the contentType. I ran into problems using $.post.

More to come on this...

Thursday, June 4, 2015

TDD Resources

This is a quick and dirty post listing some (imho) good resources for TDD.

Definitions

  • Unit Test - A test which verifies a unit of work. There must not be any interaction with external resources (databases, file systems, etc.). May or may not test more than one component or class.
  • Integration Test - A test which verifies a unit of work. These tests interact with external resources (databases, file systems, etc.).

Books

Blog Posts
Videos

Wednesday, May 20, 2015

NancyFX Notes: Static Content

NancyFX Notes

This is part of a set of articles that are my developer notes for working with Nancy. Taken from the Nancy introduction, "Nancy is a lightweight, low-ceremony, framework for building HTTP based services on .Net and Mono." It's (she's?) great for building microservices and other things.

Static Content

Static content are files like images, JavaScript files, css files, etc. Nancy automatically supports static files which are placed in the Content directory. The example on GitHub has custom directories for the 3rd-party scripts and the application-specific scripts. These are Scripts and App directories.



Other directories can be included by adding to NancyConventions.StaticContentConventions property. Do this by overriding the ConfigureConventions method in your bootstrapper.



The shot from Fiddler below shows a before and after. The calls from 5-8 were made before the additions to the bootstrapper. The later calls show that the changes enabled Nancy hosting the files in those directories.