Patterns & Abstractions

Patterns and Abstractions

My central architectural pattern of choice is CQRS.


Commands

Actions that change something and return nothing

public interface ICommandHandler<TCommand> where TCommand : ICommand
{
    void Execute(TCommand command);
}

Queries

Actions that return something and change nothing

public interface IQuery<TResult>
{
}

public interface IQueryHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
    TResult Execute(TQuery query);
}

Mediators

A combination of commands and queries

There are two mediator abstractions. One that essentially mediates a call to a command and returns nothing

public interface IMediator
{
}

public interface IMediatingHandler<TRequest> where TRequest : IMediator
{
    void Execute(TRequest request);
}

And one that mediates the call to a query and returns something

public interface IMediator<TResult> : IMediator
{
}

public interface IMediatingHandler<TRequest, TResult> where TRequest : IMediator<TResult>
{
    TResult Execute(TRequest request);
}

Events (Observers)

Side effects

public interface IEvent
{
}

public interface ISubscriber<TEvent> where TEvent : IEvent
{
    void Handle(TEvent param);
}

Here are some example events: here we have 3 generic events to cater for pre and post an activity. These events are designed to be triggered before and after calling each QueryHandler<,> and CommandHandler<>.

public sealed class OnBefore<TRequest> : IEvent
{
    public OnBefore(TRequest response)
    {
        this.Request = response;
    }

    public TRequest Request { get; private set; }
}

public sealed class OnAfter<TRequest> : IEvent
{
    public OnAfter(TRequest request)
    {
        this.Request = request;
    }

    public TRequest Request { get; private set; }
}

public sealed class OnAfter<TRequest, TResponse> : IEvent
{
    public OnAfter(TRequest request, TResponse response)
    {
        this.Request = request;

        this.Response = response;
    }

    public TRequest Request { get; private set; }

    public TResponse Response { get; private set; }
}

Decorators

Cross cutting concerns

Decorators can be logically divided into 2 groups.

Specific cross cutting concerns (A Strategy)

Decorators that affect only one thing. Rather than open up the existing fully unit tested code (in doing so we would break the S and the O in the SOLID principles) we wrap existing code with a decorator.

General cross cutting concerns (Aspect Oriented Programming)

Code that should be applied to all (or the majority of) a specific service type. User activity logging is an example of this. All commands (and queries) can be wrapped with a generic decorator that records certain details on the requested action.

Debug IIS/global.asax within Visual Studio

Taken from this SO answer

You may create a post-build event which changes the timestamp of a web.config file. I used a touch.exe tool from http://www.stevemiller.net/apps/. You also need to set the “Run the post-build event” to Always.

With this option set anytime you start the debugger, web.config timestamp is getting updated causing application (thus IIS pool) restart on the first request – but at this point you are already attached to this process so your Application_ event breakpoints should work.

A web based Markdown file viewer (IIS/PHP)

Firstly, thanks must go to the author of this post.

  • Put markdown.php in your blog site folder.
  • Add a posts folder and place all your md files into it.
  • Create a content folder and download google prettify and bootstrap
  • Create index.php
<html>
<head>
<link href='content/bootstrap.css' type='text/css' rel='stylesheet' />
<style>
* {
 font-family: Verdana;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-10">
<img src='content/logo.png' class='pull-right' />
<h1>Posts</h1>
<?php

$list = glob('posts/*.md');
foreach($list as $post)
{
    $postSansTXT = substr($post, 6);

    $PostMarkdown = file_get_contents($post);
    include_once "markdown.php";
    $PostHTML = Markdown($PostMarkdown);

    $doc = new DOMDocument();
    $doc->loadHTML($PostHTML);
    $h1 = $doc->getElementsByTagName('h1');

    echo "<p><a href='$postSansTXT'>";
    echo $h1->item(0)->nodeValue;
    echo '</a></p>';
}

?>
</div>
</div>
</div>
</body>
  • Create post.php
<html>
<head>
<link href='content/github.css' type='text/css' rel='stylesheet' />
<link href='content/bootstrap.css' type='text/css' rel='stylesheet' />
<script type='text/javascript' src='content/prettify.js'></script>
<style>
* {
 font-family: Verdana;
}
</style>
</head>
<body onload='prettyPrint();'>
<div class="container">
<div class="row">
<div class="col-md-10">
<img src='content/logo.png' class='pull-right' />
<?php 

$post = "C:/inetpub/wwwroot/Capita.E1f.Blog/posts/" . $_GET["file"] . ".md";

$PostMarkdown = file_get_contents($post);

include_once "markdown.php";

$PostHTML = Markdown($PostMarkdown);

echo $PostHTML;

?>
</div>
</div>
</div>
</body>
  • Create web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1" stopProcessing="true">
                    <match url="^(.*).md$" ignoreCase="false" />
                    <action type="Rewrite" url="post.php?file={R:1}" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>
  • Modify markdown.php

Line 42 from false to true:

@define( 'MARKDOWN_CODE_ATTR_ON_PRE',   true );

Line 2971 add prettyprint:

if ($classname != "") {
    if ($classname{0} == '.')
        $classname = substr($classname, 1);
    $attr_str = ' class="prettyprint '.$this->code_class_prefix.$classname.'"';
} else {
    $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs);
}

Preventing Automatic Restart for Windows Updates on Windows 8

To prevent Windows 8 automatic restart for Windows updates, administrators must follow the steps given as below:
1. Log on to Windows 8 computer with the account that has elevated privileges.
2. Click Desktop tile from the Start screen to view the desktop.
3. On the desktop screen, press the Windows + R keys simultaneously to initiate the Run command box.
4. On the opened box, type GPEDIT.MSC command in the available field and press Enter.
5. From the Local Group Policy Editor window, in the left pane, double-click to expand Computer Configuration.
6. Form the displayed options, go to Administrative Templates > Windows Components > Windows Update.
7. From the displayed policies in the right pane, double-click No auto-restart with logged on users for scheduled automatic updates installations.
8. On the No auto-restart with logged on users for scheduled automatic updates installations box, click to select the Enabled radio button to prevent automatic restart after updates installation of Windows 8.

Referencing the container is not automatically the Service Locator Anti-pattern

This post will briefly describe when it is ok to reference a container in your application.

What is a Container?

A container is an object that you delegate the responsibility of creating and managing your object graphs and object lifetimes.

What is a Service?

A Service is an object that exposes one or more methods.

What is the Service Locator Anti-pattern?

The best description of Service Locator Anti-pattern can be found on Mark Seemann’s blog here.

A common example is a central, global, static reference to a container that is accessible from anywhere in the code. The service locator is used to find instances of services. Your code can reference this service locator from anywhere and can call into it at any time.

E.g.:

public class BusinessObject {
    public void Method() {
        var service = ServiceLocator.Resolve<IService>();
    }
}

Code that references the service locator cannot run without the service locator and the service locator hides a classes dependencies.

If you’re not supposed to reference the container all over the place how do you resolve dependencies within your classes?

You resolve dependencies using the Dependency Inversion Principle; injecting dependencies into each object.

Surely you must have some references to the container?

You have to reference the container to configure it and to Resolve() instances from it. You have to do some Service Locator type activity and there is no escape from that fact.

Frameworks such as Microsoft’s MVC framework hide the fact that the container is acting as a service locator.

IDependencyResolver

Defines the methods that simplify service location and dependency resolution.

You cannot avoid Service Location; you can carefully govern and control when and where it happens.

Where is it ok to reference the container?

You can reference the container anywhere in the Composition Root

What is the Composition Root?

The composition root is the logical place that you configure the container.

A common misconception is that the Composition Root has to be in one file. This is not strictly true, but it does need to be logically separated from the rest of your solution.

  • It can be spread across multiple files
  • It can be a folder filled with classes
  • It can be a namespace filled with classes
  • It should contain all the code that references the container

As Mark Seemann advises here, the Composition Root should be

As close as possible to the application’s entry point.

When is it ok to reference the container?

The main driver for needing a hard reference to the container is to dynamically resolve objects based on data that is only known at run-time.

As mentioned already an example of this is the MVC framework that will resolve an object graph for each request based on the route of the request.

The Golden Rule

A class that references the container should not return a service. As stated above a service is a class that exposes one or more methods. A class that references the container should return the result of one or more service method calls or nothing (e.g. void, null, etc.).

Sticking to this rule effectively means your classes are acting as a proxy.

If your class references the container and returns a service then it is more akin to a factory and may be acting as a Service Locator.

What does a good example look like?

public sealed class EventPublisher : IEventPublisher {
    private readonly Container container;

    public EventPublisher(Container container) {
        this.container = container;
    }

    public void Publish<TEvent>(TEvent eventMessage) where TEvent : class, IEvent {
        var subscriber = container.GetInstance<ISubscriber<TEvent>>();
        subscriber.Handle(eventMessage);
    }
}

Another good example?

sealed class QueryProcessor : IQueryProcessor {
    private readonly Container container;

    public QueryProcessor(Container container) {
        this.container = container;
    }

    public TResult Process<TResult>(IQuery<TResult> query) {
        var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
        dynamic handler = container.GetInstance(handlerType);
        return handler.Handle((dynamic)query);
    }
}

source

What does a mistake look like?

public class LogResolverService : ILogResolverService {
    private readonly Container container;

    public LogResolverService(Container container) {
        container = container;
    }

    public ILogger<T> Resolve<T>() {
        return this.container.GetInstance<ILogger<T>>();
    }
}

source

Wrapping up

Referencing the container is definitely not the Service Locator Anti-pattern if you stick to the golden rule.

Enjoy!

@qujck

Elmah in the Enterprise: a 3 tier solution

Elmah is a fantastic error logging solution for ASP.NET, but it has one “feature” that can prevent its adoption in the enterprise – errors can be stored on the local drive or to a database, neither of which are working for my employer.

Error details should not be stored on the web server and the web server cannot be given access to the data server.

So here’s my solution, a WebApi service for the application tier. The code makes use of RestSharp despite the lack of support. The trick in this code is serializing the Error class using the BinaryFormatter and sending it over the wire as a byte array.

The Repository:

This implementation is for Sql Server but the Repository can be easily changed to use any of the other providers.

This could be enhanced to read the Elmah config section of the web.config file.

public class ElmahRepository
{
    private readonly string logConnectionString;
    private readonly string elmahApplicationName;

    public ElmahRepository(
        string LogConnectionString, 
        string ElmahApplicationNameAppSetting)
    {
        this.logConnectionString = LogConnectionString;
        this.elmahApplicationName = ElmahApplicationNameAppSetting;
    }

    public string Log(Error error)
    {
        var logger = error.ApplicationName;
        return this.Logger.Log(error);
    }

    private SqlErrorLog Logger
    {
        get
        {
            var logger = new SqlErrorLog(this.logConnectionString);
            logger.ApplicationName = this.elmahApplicationName;
            return logger;
        }
    }
}

And an integration test:

public class ElmahRepositoryTests
{
    [Fact]
    public void Log_Always_Succeeds()
    {
        var exception = new InvalidOperationException("Log_Always_Succeeds");
        var error = new Error(exception);
        var repository = this.RepositoryFactory();

        var response = repository.Log(error);
        Guid result;
        Assert.True(Guid.TryParse(response, out result));
        Assert.NotEqual(
            Guid.Parse("{00000000-0000-0000-0000-000000000000}"),
            result);
    }

    private ElmahRepository RepositoryFactory()
    {
        return new ElmahRepository(
            "server=.;database=<>;user id=<>;password=<>;",
            "Test");
    }
}

The Controller:

Note: you have to use PUT with RestSharp to get the response.

[RoutePrefix("Log")]
public class LogController : ApiController
{
    private readonly ElmahRepository elmahRepository;

    public LogController(
        ElmahRepository elmahRepository)
    {
        this.elmahRepository = elmahRepository;
    }

    [Route("Add")]
    [HttpPut]
    public string Add([FromBody]byte[] data)
    {
        return this.elmahRepository.Log(ElmahHelpers.ToError(data));
    }
}

And its integration tests

The use of NtlmAuthenticator is not mandatory.

public class LogControllerTests
{
    [Fact]
    public void Add_Always_Succeeds()
    {
        var error = new Error(
            new InvalidOperationException("Add_Always_Succeeds"));
        var controller = this.ControllerFactory();

        var response = controller.Add(ElmahHelpers.ToByteArray(error));
        Guid result;

        Assert.True(Guid.TryParse(response, out result));
        Assert.NotEqual(
            Guid.Parse("{00000000-0000-0000-0000-000000000000}"),
            result);
    }

    [Fact]
    public void Add_MadeAsARestRequest_Succeeds()
    {
        var error = new Error(
            new InvalidOperationException("Add_MadeAsARestRequest_Succeeds"));
        var client = this.RestClientFactory();
        var request = new RestRequest("Log/Add");
        request.RequestFormat = DataFormat.Json;
        request.AddBody(ElmahHelpers.ToByteArray(error));

        var response = client.Put(request).Content.Replace(@"""", "");

        Guid result;
        Assert.True(Guid.TryParse(response, out result));
        Assert.NotEqual(
            Guid.Parse("{00000000-0000-0000-0000-000000000000}"),
            result);
    }

    private RestClient RestClientFactory()
    {
        var client = new RestClient("http://<server>/<path>/");
        client.Authenticator = new NtlmAuthenticator();

        return client;
    }

    private LogController ControllerFactory()
    {
        var controller = new LogController(
            this.ElmahRepositoryFactory());

        var context = new HttpControllerContext
        {
            RequestContext = new HttpRequestContext
            {
                Principal = new GenericPrincipal(
                    System.Security.Principal.WindowsIdentity.GetCurrent(),
                    null)
            }
        };

        controller.ControllerContext = context;
        return controller;
    }

    private ElmahRepository ElmahRepositoryFactory()
    {
        return new ElmahRepository(
            "server=.;database=<>;user id=<>;password=<>;",
            "Test");
    }
}

The BinaryFormatter helpers:

public static class ElmahHelpers
{
    public static byte[] ToByteArray(Error error)
    {
        var bf = new BinaryFormatter();
        using (var ms = new MemoryStream())
        {
            bf.Serialize(ms, error);
            return ms.ToArray();
        }
    }

    public static Error ToError(byte[] data)
    {
        using (var memStream = new MemoryStream())
        {
            var binForm = new BinaryFormatter();
            memStream.Write(data, 0, data.Length);
            memStream.Seek(0, SeekOrigin.Begin);
            var obj = (Error)binForm.Deserialize(memStream);
            return obj;
        }
    }
}

The implementation of ErrorLog that calls the WebApi controller:

I have simply chosen to throw an UnauthorizedAccessException if any attempt is made to read the errors.

public class RestErrorLog : ErrorLog
{
    private readonly string connectionString;

    public RestErrorLog(IDictionary config)
    {
        if (config == null)
        {
            throw new ArgumentNullException("config");
        }

        this.connectionString = (string)config["connectionString"] ?? string.Empty;

        if (this.connectionString.Length == 0)
        {
            throw new Elmah.ApplicationException("Connection string is missing for the Rest error log.");
        }
    }

    public override string Name
    {
        get
        {
            return "Rest Error Log.";
        }
    }

    public override string Log(Error error)
    {
        var client = new RestClient(this.connectionString);
        client.Authenticator = new NtlmAuthenticator();
        var request = new RestRequest("Log/Add");
        request.RequestFormat = DataFormat.Json;
        request.AddBody(ToByteArray(error));

        var result = client.Put(request).Content.Replace(@"""", "");

        return result;
    }

    public override int GetErrors(int pageIndex, int pageSize, System.Collections.IList errorEntryList)
    {
        throw new UnauthorizedAccessException(
            string.Format("RestErrorLog.GetErrors({0}, {1})", pageIndex, pageSize));
    }

    public override ErrorLogEntry GetError(string id)
    {
        throw new UnauthorizedAccessException(
            string.Format("RestErrorLog.GetError({0})", id));
    }

    private static byte[] ToByteArray(Error error)
    {
        var bf = new BinaryFormatter();
        using (var ms = new MemoryStream())
        {
            bf.Serialize(ms, error);
            return ms.ToArray();
        }
    }
}

And finally the entry in web.config to wire it all together:

Note that applicationName should match the value injected into the Repository.

<elmah xmlns="http://Elmah.Configuration">
  <errorLog 
    type="<namespace>.RestErrorLog, <assembly>" 
    applicationName="Test" 
    connectionString="http://<server>/<path>/"></errorLog>
</elmah>

Woohoo! Elmah in the Enterprise :-)

Trying to get JetPack Markdown with code to play nicely with WordPress

After a lot of trial and error here’s how I got code in markdown to work in WordPress.

2 plug-ins are required

Smart Syntax for adding class="prettyprint lang-xyz to the <pre> tag

and

Prettify Code Syntax for the most flexible syntax highlighter I have ever found for WordPress.

Finally, go to Settings - Prettify Code Syntax and change the top of the Custom css to this

.prettyprint .com       { color: #008000; }
.prettyprint .str, .tag { color: #A31515; }
.prettyprint .kwd, .atv { color: #0000FF; }
.prettyprint .typ       { color: #2B91AF; }
.prettyprint .lit, .atn { color: #FF0000; }
.prettyprint .pun, .pln { color: #000000; }
.prettyprint .dec       { color: #800080; }

pre.prettyprint, 
code.prettyprint, 
pre.prettyprint code,
.post-content pre.prettyprint,
.post-content code.prettyprint,
.post-content pre.prettyprint code,
.comment-content pre.prettyprint,
.comment-content code.prettyprint,
.comment-content pre.prettyprint code  {
    background-color: #F6F6F6; display: block;
}

It’s ok but there still problems with the <pre> tags being rendered differently between the home page and the individual post page and it shrinks down to almost nothing on a mobile device.