Skip to content

Jimmy Bogard
Syndicate content
Strong opinions, weakly held
Updated: 10 hours 45 min ago

Integrating MediatR with Web API

Tue, 01/20/2015 - 19:25

One of the design goals I had in mind with MediatR was to limit the 3rd party dependencies (and work) needed to integrate MediatR. To do so, I only take a dependency on CommonServiceLocator. In MediatR, I need to resolve instances of request/notification handlers. Rather than build my own factory class that others would need to implement, I lean on CSL to define this interface:

public interface IServiceLocator : IServiceProvider
{
    object GetInstance(Type serviceType);
    object GetInstance(Type serviceType, string key);
    IEnumerable<object> GetAllInstances(Type serviceType);
    TService GetInstance<TService>();
    TService GetInstance<TService>(string key);
    IEnumerable<TService> GetAllInstances<TService>();
}

But that wasn’t quite enough. I also wanted to support child/nested containers, which meant I didn’t want a single instance of the IServiceLocator. Typically, when you want a component’s lifetime decided by a consumer, you depend on Func<Foo>. It turns out though that CSL already defines a delegate to provide a service locator, aptly named ServiceLocatorProvider:

public delegate IServiceLocator ServiceLocatorProvider();

In resolving handlers, I execute the delegate to get an instance of an IServiceLocatorProvider and off we go. I much prefer this approach than defining my own yet-another-factory-interface for people to implement. Just not worth it. As a consumer, you will need to supply this delegate to the mediator.

I’ll show an example using StructureMap. The first thing I do is add a NuGet dependency to the Web API IoC shim for StructureMap:

Install-Package StructureMap.WebApi2

This will also bring in the CommonServiceLocator dependency and some files to shim with Web API:

image

I have the basic building blocks for what I need in order to have a Web API project using StructureMap. The next piece is to configure the DefaultRegistry to include handlers in scanning:

public DefaultRegistry() {
    Scan(
        scan => {
            scan.TheCallingAssembly();
            scan.AssemblyContainingType<PingHandler>();
            scan.WithDefaultConventions();
			scan.With(new ControllerConvention());
            scan.AddAllTypesOf(typeof(IRequestHandler<,>));
            scan.AddAllTypesOf(typeof(IAsyncRequestHandler<,>));
            scan.AddAllTypesOf(typeof(INotificationHandler<>));
            scan.AddAllTypesOf(typeof(IAsyncNotificationHandler<>));
        });
    For<IMediator>().Use<Mediator>();
}

This is pretty much the same code you’d find in any of the samples in the MediatR project. The final piece is to hook up the dependency resolver delegate, ServiceLocatorProvider. Since most/all containers have implementations of the IServiceLocator, it’s really about finding the place where the underlying code creates one of these IServiceLocator implementations and supplies it to the infrastructure. In my case, there’s the Web API IDependencyResolver implementation:

public IDependencyScope BeginScope()
{
    IContainer child = this.Container.GetNestedContainer();
    return new StructureMapWebApiDependencyResolver(child);
}

I modify this to use the current nested container and attach the resolver to this:

public IDependencyScope BeginScope()
{
    var resolver = new StructureMapWebApiDependencyResolver(CurrentNestedContainer);

    ServiceLocatorProvider provider = () => resolver;

    CurrentNestedContainer.Configure(cfg => cfg.For<ServiceLocatorProvider>().Use(provider));
    
    return resolver;
}

This is also the location where I’ll attach per-request dependencies (NHibernate, EF etc.). Finally, I can use a mediator in a controller:

public class ValuesController : ApiController
{
    private readonly IMediator _mediator;

    public ValuesController(IMediator mediator)
    {
        _mediator = mediator;
    }

    // GET api/values
    public IEnumerable<string> Get()
    {
        var result = _mediator.Send(new Ping());

        return new string[] { result.Message };
    }

That’s pretty much it. How you need to configure the mediator in your application might be different, but the gist of the means is to configure the ServiceLocatorProvider delegate dependency to return the “thing that the framework uses for IServiceLocator”. What that is depends on your context, and unfortunately changes based on every framework out there.

In my example above, I’m preferring to configure the IServiceLocator instance to be the same instance as the IDependencyScope instance, so that any handler instantiated is from the same composition root/nested container as whatever instantiated my controller.

See, containers are easy, right?

(crickets)

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Combating the lava-layer anti-pattern with rolling refactoring

Thu, 01/15/2015 - 17:37

Mike Hadlow blogged about the lava-layer anti-pattern, describing, which I have ranted about in nearly every talk I do, the nefarious issue of opinionated but lazy tech leads introducing new concepts into a system but never really seeing the idea through all the way to the end. Mike’s story was about different opinions on the correct DAL tool to use, but none of them actually ever goes away:

LavaLayer

It’s not just DALs that I see this occur. Another popular strata I see are database naming conventions, starting from:

  • ORDERS
  • tblOrders
  • Orders
  • Order
  • t_Order

And on and on – none of which add any value, but it’s not a long-lived codebase without a little bike shedding, right?

That’s a pointless change, but I’ve seen others, especially in places where design is evolving rapidly. Places where the refactorings really do add value. I called the result long-tail design, where we have a long tail of different versions of an idea or design in a system, and each successive version occurs less and less:

Long-tail and lava-layer design destroy productivity in long-running projects. But how can we combat it?

Jimmy’s rule of 2: There can be at most two versions of a concept in an application

In practice, what this means is we don’t move on to the next iteration of a concept until we’ve completely refactored all existing instances. It starts like this:

image

A set of functionality we don’t like all exists in one version of the design. We don’t like it, and want to make a change. We start by carving out a slice to test out a new version of the design:

image

We poke at our concept, get input, refine it in this one slice. When we think we’re on to something, we apply it to a couple more places:

image

It’s at this point where we can start to make a decision: is our design better than the existing design? If not, we need to roll back our changes. Not leave it in, not comment it out, but roll it all the way back. We can always do our work in a branch to preserve our work, but we need to make a commitment one way or the other. If we do commit, our path forward is to refactor V1 out of existence:

image

image

image

image

image

We never start V3 of our concept until we’ve completely eradicated V1 – and that’s the law of 2. At most two versions of our design can be in our application at any one time.

We’re not discouraging refactoring or iterative/evolutionary design, but putting in parameters to discipline ourselves.

In practice, our successive designs become better than they could have been in our long-tail/lava-layer approach. The more examples we have of our idea, the stronger our case becomes that our idea is better. We wind up having a rolling refactoring result:

output_yWnRTm

A rolling refactoring is the only way to have a truly evolutionary design; our original neanderthal needs to die out before moving on to the next iteration.

Why don’t we apply a rolling refactoring design? Lots of excuses, but ultimately, it requires courage and discipline, backed by tests. Doing this without tests isn’t courage – it’s reckless and developer hubris.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Generic variance in DI containers

Tue, 01/13/2015 - 03:02

DI containers, as complex as they might be, still provide quite a lot of value when it comes to defining and realizing the composition of your system. I use the variance features quite a bit, especially in my MediatR project and composing a rich pipeline. A side note, one of the design goals of MediatR is not to take any dependency on a 3rd party DI container. I instead take a dependency on Common Service Locator, which all major DI containers already have. As part of this exercise, I still wanted to provide examples of all major containers, and this led me to figure out which containers supported what.

I looked at the major containers out there:

  • Autofac
  • Ninject
  • Simple Injector
  • StructureMap
  • Unity
  • Windsor

And tried to build examples of using MediatR. As part of this, I was able to see what containers supported which scenarios, and how difficult it was to achieve this.

The scenario is this: I have an interface, IMediator, in which I can send a single request/response or a notification to multiple recipients:

public interface IMediator
{
    TResponse Send<TResponse>(IRequest<TResponse> request);

    Task<TResponse> SendAsync<TResponse>(IAsyncRequest<TResponse> request);

    void Publish<TNotification>(TNotification notification)
        where TNotification : INotification;

    Task PublishAsync<TNotification>(TNotification notification)
        where TNotification : IAsyncNotification;
}

I then created a base set of requests/responses/notifications:

public class Ping : IRequest<Pong>
{
    public string Message { get; set; }
}
public class Pong
{
    public string Message { get; set; }
}
public class PingAsync : IAsyncRequest<Pong>
{
    public string Message { get; set; }
}
public class Pinged : INotification { }
public class PingedAsync : IAsyncNotification { }

I was interested in looking at a few things with regards to container support for generics:

  • Setup for open generics (registering IRequestHandler<,> easily)
  • Setup for multiple registrations of open generics (two or more INotificationHandlers)
  • Setup for generic variance (registering handlers for base INotification/creating request pipelines)

My handlers are pretty straightforward, they just output to console:

public class PingHandler : IRequestHandler<Ping, Pong> { /* Impl */ }
public class PingAsyncHandler : IAsyncRequestHandler<PingAsync, Pong> { /* Impl */ }

public class PingedHandler : INotificationHandler<Pinged> { /* Impl */ }
public class PingedAlsoHandler : INotificationHandler<Pinged> { /* Impl */ }
public class GenericHandler : INotificationHandler<INotification> { /* Impl */ }

public class PingedAsyncHandler : IAsyncNotificationHandler<PingedAsync> { /* Impl */ }
public class PingedAlsoAsyncHandler : IAsyncNotificationHandler<PingedAsync> { /* Impl */ }

I should see a total of seven messages output from the result of the run. Let’s see how the different containers stack up!

Autofac

Autofac has been around for quite a bit, and has extensive support for generics and variance. The configuration for Autofac is:

var builder = new ContainerBuilder();
builder.RegisterSource(new ContravariantRegistrationSource());
builder.RegisterAssemblyTypes(typeof (IMediator).Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof (Ping).Assembly).AsImplementedInterfaces();

Autofac does require us to explicitly add a registration source for recognizing contravariant interfaces (covariant is a lot rarer, so I’m ignoring that for now). With minimal configuration, Autofac scored perfectly and output all the messages.

Open generics: yes, implicitly

Multiple open generics: yes, implicitly

Generic contravariance: yes, explicitly

Ninject

Ninject has also been around for quite a while, and also has extensive support for generics. The configuration for Ninject looks like:

var kernel = new StandardKernel();
kernel.Components.Add<IBindingResolver, ContravariantBindingResolver>();
kernel.Bind(scan => scan.FromAssemblyContaining<IMediator>()
    .SelectAllClasses()
    .BindDefaultInterface());
kernel.Bind(scan => scan.FromAssemblyContaining<Ping>()
    .SelectAllClasses()
    .BindAllInterfaces());
kernel.Bind<TextWriter>().ToConstant(Console.Out);

Ninject was able to display all the messages, and the configuration looks very similar to Autofac. However, that “ContravariantBindingResolver” is not built in to Ninject and is something you’ll have to spelunk Stack Overflow to figure out. It’s somewhat possible when you have one generic parameter, but for multiple it gets a lot harder. I won’t embed the gist as it’s quite ugly, but you can find the full resolver here.

Open generics: yes, implicitly

Multiple open generics: yes, implicitly

Generic contravariance: yes, with user-built extensions

Simple Injector

Simple Injector is a bit of an upstart from the same folks behind NancyFx someone not related to NancyFx at all yet has a very similar Twitter handle, and it focuses really on the simple, straightforward scenarios. This is the first container that requires a bit more to hook up:

var container = new Container();
var assemblies = GetAssemblies().ToArray();
container.Register<IMediator, Mediator>();
container.RegisterManyForOpenGeneric(typeof(IRequestHandler<,>), assemblies);
container.RegisterManyForOpenGeneric(typeof(IAsyncRequestHandler<,>), assemblies);
container.RegisterManyForOpenGeneric(typeof(INotificationHandler<>), container.RegisterAll, assemblies);
container.RegisterManyForOpenGeneric(typeof(IAsyncNotificationHandler<>), container.RegisterAll, assemblies);

While multiple open generics is supported, contravariance is not. In fact, to hook up contravariance requires quite a few hoops to jump through to set it up. It’s documented, but I wouldn’t call it “out of the box” because you have to build your own wrapper around the handlers to manually figure out the handlers to call. UPDATE: as of 2.7, contravariance *is* supported out-of-the-box. Configuration is the same as it is above, the variance now “just works”.

Open generics: yes, explicitly

Multiple open generics: yes, explicitly

Generic contravariance: no yes, implicitly

StructureMap

This is the most established container in this list, and one I’ve used the most personally. StructureMap is a little bit different in that it applies conventions during scanning assemblies to determine how to wire requests for types up. Here’s the StructureMap configuration:

var container = new Container(cfg =>
{
    cfg.Scan(scanner =>
    {
        scanner.AssemblyContainingType<Ping>();
        scanner.AssemblyContainingType<IMediator>();
        scanner.WithDefaultConventions();
        scanner.AddAllTypesOf(typeof(IRequestHandler<,>));
        scanner.AddAllTypesOf(typeof(IAsyncRequestHandler<,>));
        scanner.AddAllTypesOf(typeof(INotificationHandler<>));
        scanner.AddAllTypesOf(typeof(IAsyncNotificationHandler<>));
    });
});

I do have to manually wire up the open generics in this case.

Open generics: yes, explicitly

Multiple open generics: yes, explicitly

Generic contravariance: yes, implicitly

Unity

And now for the most annoying container I had to deal with. Unity doesn’t like one type registered with two implementations, so you have to do extra work to even be able to run the application with multiple handlers for a message. My Unity configuration is:

container.RegisterTypes(AllClasses.FromAssemblies(typeof(Ping).Assembly),
   WithMappings.FromAllInterfaces,
   GetName,
   GetLifetimeManager);

/* later down */

static bool IsNotificationHandler(Type type)
{
    return type.GetInterfaces().Any(x => x.IsGenericType && (x.GetGenericTypeDefinition() == typeof(INotificationHandler<>) || x.GetGenericTypeDefinition() == typeof(IAsyncNotificationHandler<>)));
}

static LifetimeManager GetLifetimeManager(Type type)
{
    return IsNotificationHandler(type) ? new ContainerControlledLifetimeManager() : null;
}

static string GetName(Type type)
{
    return IsNotificationHandler(type) ? string.Format("HandlerFor" + type.Name) : string.Empty;
}

Yikes. Unity handles the very simple case of open generics, but that’s about it.

Open generics: yes, implicitly

Multiple open generics: yes, with user-built extension

Generic contravariance: derp

Windsor

The last container in this completely unnecessarily long list is Windsor. Windsor was a bit funny, it required a lot more configuration than others, but it was configuration that was built in and very wordy. My Windsor configuration is:

var container = new WindsorContainer();
container.Register(Classes.FromAssemblyContaining<IMediator>().Pick().WithServiceAllInterfaces());
container.Register(Classes.FromAssemblyContaining<Ping>().Pick().WithServiceAllInterfaces());
container.Kernel.AddHandlersFilter(new ContravariantFilter());

Similar to Ninject, the simple scenarios are built-in, but the more complex need a bit of Stack Overflow spelunking. The “ContravariantFilter” is very similar to the Ninject implementation, with the same limitations as well.

Open generics: yes, implicitly

Multiple open generics: yes, implicitly

Generic contravariance: yes, with user-built extension

Final score

Going in, I thought the containers would be closer in ability for a feature like these that are pretty popular these days. Instead, they’re miles apart. I originally was going to use this as a post to complain that there are too many DI containers in the .NET space, but honestly, the feature set and underlying models are so completely different it would take quite a bit of effort to try to consolidate and combine projects.

What is pretty clear from my experience here is that Unity as a choice is probably a mistake.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

Los Techies 2014 Year in Review

Tue, 01/06/2015 - 19:53

Another year of blogging, another year of inane, vapid and vacuous posts. But enough about my writing, let’s pore into the numbers behind blogging at Los Techies. We saw a departure of one of our most prolific bloggers in Derick Bailey, who finally exited after many reprimands from Pablo to “please stop trying to make JavaScript happen”. And after some notable additions to the team in 2013, we had no new additions to our group last year. I attribute this to Los Techies needing to “find itself” after the Derick Bailey debacle.

Traffic-wise, Los Techies saw growth year-over-year in behavior:

image

I have no idea if these numbers are good or not, but “green” seems good and “red” seems bad. Pageviews clocked in at over 4.5 million, and that seems like a big number. For comparison purposes, we had 2.5 million in 2012, growing by the same number but a slowed rate. 2014 also marked the year of the death of Google Reader, which brought our subscriber count from Some Big But Probably Wrong Number to a Smaller But Who Knows This Seems Made Up number. Time spent on LT also went down, which I’ll dig into shortly.

All time, we’ve received 15M pageviews and 11M unique pageviews, which means that between 25-30% of our traffic all time came within the past year.

How did individual posts do? In this list, we see a mix of old and new:

image

Well, it looks like it’s the Jimmy and Gabriel show. The top post is one about a standup desk in which I felt like the equivalent of a Picard trying to sleep on a Klingon bed. It only caused pain and I didn’t really prove anything to anyone. Gabriel’s excellent blog series on a mediocre Javascript framework generated a lot of traffic, as did a couple of my posts that just don’t seem to die. The View Models post in particular is one I’m particularly proud to have made my stamp on the world, and one of the few posts from 5+ years ago that I still look back and agree with myself.

The all time numbers are pretty funny, “one of these things is not like the others”

image

Many moons ago, we were hosted on a .NET blogging engine whose name I have burned from my memory. Naturally, older posts dominate the all-time list simply because they’ve had longer time to accrue pageviews, similar to old Stack Overflow answers that I’m slowly milking my way to 10K rep.

How did individual bloggers stack up? You might not ask this question, but I did, being a narcissistic sort of fella.

image

I win! Something. Interestingly, although I received over 40% of total pageviews, users only spent less than a minute on my blogs. Derick gets over 4 minutes of eyeball time. My bounce rate is waaaaaaay lower than others, but I have no idea what it means. I choose to believe it’s like a golf score, and lower is better. Or more likely, others wrote longer, more descriptive, and less ClickHole-worthy posts than I.

I’d pull up acquisition numbers, but it says that 75% of our traffic came from organic search, and 97% of that came from the search term of “(not provided)”. I can only assume this is because one of our bloggers wrote about Heartbleed, and Google retaliated by removing those inbound values.

Finally, where did our users come from?

image

Mostly the US, but also some EU/UK, and a small number coming from across the other pond.

Browser-wise, it’s still dominated by Chrome:

image

We see some unfortunate souls using “Mozilla Compatible Agent”, about the least sexy browser name I’ve seen. Waaaaaaay down the list I can see browser agents of “Do not spy on me!”. Done and done. I also see people using their game consoles, as “Nintendo Browser”, “Playstation Vita Browser” and “Playstation 3” show up on the list. I don’t know about you, but right after I’m done with yet another Skyrim session, I go straight to learning about Angular on my TV.

Interestingly enough, we don’t a lot of mobile traffic – 92% of our traffic comes straight from desktop. On the desktop, Windows beats Mac 3 to 1, and Linux 8 to 1. Of those mobile hits, about half come from iOS, 44% from Android, and the rest from Windows Phone/BlackBerry (?!). Not exactly what I expected, where supposedly mobile is a thing.

All in all, I’m proud of the content we put out this past year.  Thanks again to all of our readers, and sincerest apologies to mine. Here’s to a great new year, more great content, and if we get around to it, another Pablo’s Fiesta.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

AutoMapper 3.3 feature: parameterized projections

Tue, 12/30/2014 - 16:44

Back in AutoMapper 3.1, I added a feature to allow for runtime values to be used in mappings:

Mapper.Initialize(cfg => {
    cfg.CreateMap<Src, Dest>()
        .ForMember(d => d.UserName,
           opt => opt.ResolveUsing(ctx => ctx.Items["CurrentUserName"]));
});

// In my controller action

var model = Mapper.Map<Src, Dest>(src,
   opt => opt.Items["CurrentUserName"] = User.Identity.Name);

This worked great for runtime mappings, but wasn’t supported in the LINQ projections. These days, I’m pretty much solely using the LINQ projections in concert with some sort of data access object/ORM (ISession, DbContext, IDocumentSession etc.).

Allowing for runtime values in LINQ queries is fairly straightforward without AutoMapper – you can create a closure that gets captured in the resulting expression tree:

dbContext.WorkItems.Select(src => {
    Name = src.Name,
    User = User.Identity.Name
});

The resulting closure “helper” class effectively allows for a parameterized query. So how might we accomplish this with AutoMapper? Our first thought might be to use the “MapFrom” method with the runtime value supplied:

Mapper.CreateMap<Src, Dest>()
   .ForMember(d => d.UserName, opt => opt.MapFrom(/* ????? */));

But the problem here is mapping definitions are static, defined once and reused throughout the lifetime of the application. Before 3.3, you would need to re-define the mapping on every request, with the hard-coded value. And since the mapping configuration is created in a separate location than our mapping execution, we need some way to introduce a runtime parameter in our configuration, then supply it during execution.

This is accomplished in two parts: the mapping definition where we create a runtime parameter, then at execution time when we supply it. To create the mapping definition with a runtime parameter, we “fake” a closure that includes a named local variable:

Mapper.Initialize(cfg => {

   string userName = null;
   cfg.CreateMap<Source, Dest>()
        .ForMember(d => d.UserName, 
            opt => opt.MapFrom(src => userName)
        );
});

We can’t access the “real” value we’d use during execution in our configuration, so we create a stand-in that still creates a closure for us. The underlying expression tree that gets built recognizes this external input and creates a placeholder parameter to be supplied at runtime. When executing the projection, we can supply our parameter value with either a dictionary or an anonymous object:

dbContext.Sources
   .Project().To<Dest>(new {userName = User.Identity.Name})
   .ToList();

// Dictionary fun
dbContext.Sources
   .Project().To<Dest>(new Dictionary<string, object> {["userName"] = User.Identity.Name})
   .ToList();

When the projection is executed by the underlying LINQ provider, the correct runtime value is replaced in the expression, letting you use per-map runtime values in your projections. You can use these runtime values in any configuration option that works off an expression:

  • MapFrom
  • ConstructProjectionUsing

Very cool stuff!

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

AutoMapper 3.3 feature: Projection conversions

Tue, 12/23/2014 - 20:42

AutoMapper 3.3 introduced a few features to complement the mapping capabilities available in normal mapping. Just like you can do ConvertUsing for completely replacing conversion between two types, you can also supply a custom projection expression to replace the mapping expression for two types during projection:

Mapper.CreateMap<Source, Dest>()
    .ProjectUsing(src => new Dest { Value = 10 });

Occasionally, you don’t want to replace the entire mapping, but there’s just a constructor you need to have some custom logic in:

Mapper.CreateMap<Source, Dest>()
    .ConstructProjectionUsing(src => new Dest(src.Value + 10));

AutoMapper can automatically match up source members to destination constructor parameters, but if things don’t quite line up or you need some additional logic, you have a place to do so.

Finally, AutoMapper can automatically convert types to strings (just calling .ToString()) for any time it sees a string on the destination type:

public class Order {
    public OrderTypeEnum OrderType { get; set; }
}
public class OrderDto {
    public string OrderType { get; set; }
} 
var orders = dbContext.Orders.Project().To<OrderDto>().ToList();
orders[0].OrderType.ShouldEqual("Online");

If you need to do more custom logic for a string conversion, you can either supply a global conversion (ProjectUsing) or a member conversion (MapFrom).

Finally, if you have some custom projection expansions and you only want to expand certain members on the destination, you can supply a series of projection expressions and only those explicitly specified members will be included in the resulting expansion:

dbContext.Orders.Project().To<OrderDto>(
    parameters = null,
    dest => dest.Customer,
    dest => dest.LineItems);
// or string-based
dbContext.Orders.Project().To<OrderDto>()
    parameters = null,
    "Customer",
    "LineItems");

I would usually recommend against doing this, but I’ve seen cases such as OData that this sort of scenario is expected. In the next post, I’ll cover one of the more interesting features in 3.3 – parameterized projections. Enjoy!

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

AutoMapper 3.3 feature: open generics

Sat, 12/20/2014 - 01:10

One of the interesting features of AutoMapper 3.3 is the ability to map open generic types. Open generics are those that don’t supply type parameters, like:

var openType = typeof(IEnumerable<>);

AutoMapper had some limited support for certain built-in open generics, but only the collection types. This changed in version 3.3, where you can now map any sort of open generic type:

public class Source<T> {
    public T Value { get; set; }
}

public class Destination<T> {
    public T Value { get; set; }
}

// Create the mapping
Mapper.CreateMap(typeof(Source<>), typeof(Destination<>));

Instead of using the normal syntax of the generic CreateMap method, you need to use the overload that takes type objects. This is because C# only accepts closed generic types as type parameters. This also means you can use all the configuration available for you to do member-specific mappings, but can only do them by referencing as a string instead of an expression. Not a limitation per se, but just something to be aware of.

To use the open generic mapping configuration, you can execute the mapping against a closed type:

var source = new Source<int> { Value = 10 };

var dest = Mapper.Map<Source<int>, Destination<int>>(source);

dest.Value.ShouldEqual(10);

Previously, I’d have to create maps for every closed type. With the 3.3 version, I can create map for the open type and AutoMapper can automatically figure out how to build a plan for the closed types from the open type configuration, including any customizations you’ve created.

Something that’s been asked for a while, but only recently have I figured out a clean way of implementing it. Interestingly enough, this feature is going to pave the way for programmatic, extensible conventions I’m targeting for 4.0.

Someday.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

MediatR hits 1.0

Wed, 12/17/2014 - 16:45

I’ve been using a project I wrote/borrowed/stole from a number of internal projects and existing libraries (thanks Matt) for well over a year now, and are releasing to 1.0. MediatR helps turn complex code into simplified request/response interactions, encapsulating queries, commands and notifications into a single, simple interface, collapsing complex controllers into simple pass-throughs to the real work being done:

public class ConferenceController : Controller
{
    private readonly IMediator _mediator;

    public ConferenceController(IMediator mediator)
    {
        _mediator = mediator;
    }

    public ActionResult Index(IndexQuery query)
    {
        var model = _mediator.Send(query);

        return View(model);
    }

    public ViewResult Show(ShowQuery query)
    {
        var model = _mediator.Send(query);

        return View(model);
    }

    public ActionResult Edit(EditQuery query)
    {
        var model = _mediator.Send(query);

        return View(model);
    }

    [HttpPost]
    public ActionResult Edit(ConferenceEditModel form)
    {
        var conf = _mediator.Send(form);

        return this.RedirectToActionJson(c => c.Show(new ShowQuery { EventName = conf.Name }), "Default");
    }
}

MediatR lets you send a request to a single handler:

var request = new ApproveInvoiceRequest {
   InvoiceId = invoiceID
};
ApproveInvoiceResponse response = mediator.Send(request);

Or do it asynchronously:

var request = new ApproveInvoiceRequest {
   InvoiceId = invoiceID
};
ApproveInvoiceResponse response = await mediator.SendAsync(request);

Or send a notification to a number of handlers:

var notification = new InvoiceApprovedEvent {
    InvoiceId = invoiceId
};
mediator.Publish(notification);

I’ve talked about the advantages to this pattern many times, and we use this pattern on nearly every project we encounter these days. The goal of MediatR was to create a small, unambitious implementation of the Mediator pattern, tied only to the Common Service Locator library for instantiating handlers and portable, so it works on just about every platform checkbox I could check, including Xamarin.

The GitHub repo has examples for plugging in all the major containers, and the wiki has documentation. Although the library uses Common Service Locator, it’s completely DI friendly too. Ultimately, the compositional tool is your container, and MediatR merely provides the mediation from message A to handler of A. Enjoy!

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs